一些看得懂题意但写不出的题(基本水题)

洛谷1338:
题意:给n个数: 1- n,已知逆序数为m,输出最小字典序的排列
用ans存数组

#include<iostream>
#include<algorithm>
using namespace std;
long long int n;
//试了几次 这个n一定要开 long long why??
long long m;
int a[50005];
int main(){
 cin>>n>>m;
 //如果装不下,放最后一个
 //其实是这样 判断每一位数字的时候 ,已知 长度为l最多贡献(l+1)(l)/2的逆序
 //中间有一位的数字是不定的,相当于一个突跃点,这个点前面是升序,后面是根据逆序数排成的
 // 1 2 3 x 后面再排
 //装得下 放第一个(为了字典序最小);装不下的时候,放最后一个,这样最优(??)
 //emmm这样可以贡献更多的逆序数,来满足字典序最小
 int head=1;int tail=n;
 for( int i=1;i<=n;i++){
  long long t=(n-i)*(n-i-1)/2;
  if(t>=m){
   a[head++]=i;
  }
  else{
   a[tail--]=i;
   m-=(tail-head+1);
  }
 }
 for(int i=1;i<=n;i++){
  cout << a[i]<<" ";
 }
}

2.昨天看到的一个神秘排序
排序时必须放到队首,可见最大次数为n-1次(倒序)求最小操作次数
怎么像匹配呢??这是什么原理啊。

#include<iostream>
#include<string.h>
#include<string>
#include<algorithm>
using namespace std;
int n,t;
int a[100005],b[100005];
int main(){
 cin>>t;
 while(t--){
 cin>>n;
 for(int i=1;i<=n;i++){
  cin >> a[i];
  b[i]=a[i];
 }
 //1 3 2 4    ans: 3
 // b 1234 
 // a 1324
 
 sort(b+1,b+1+n);
 int ans = 0;
 for(int i=n;i>=1;i--){
  if(b[i+ans]==a[i]){
   continue;
  }
  else ans++;
 }
 cout << ans <<endl;
}}

2.洛谷P2661 信息传递

#include <cstdio>
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm> 
#include<iomanip>
#include<cmath>
#include<string>
#include<stack>
using namespace std;
int n,ans=0x3f3f3f;
//fir存储的是第一次经过该节点的序号,那么成环时
//大小 = 遍历序号-fir[node] 
int nxt[200005],fir[200005];
//vis是否访问过, forevis:是否已经搜过 
bool vis[200005],forevis[200005];
void dfs(int node,int c){
 if(forevis[node]) return ;
 //成环 
   if(vis[node]){
  ans = min(ans,c-fir[node]);
  return; 
 }
 vis[node]=1;
 fir[node]=c;
 dfs(nxt[node],c+1);
 forevis[node]=1;
}
int main(){
 cin>>n;
 for(int i=1;i<=n;i++)cin>>nxt[i];
 for(int i=1;i<=n;i++){
  dfs(i,0);
 }
 cout << ans << endl;
 return 0;
}
发布了24 篇原创文章 · 获赞 2 · 访问量 969

猜你喜欢

转载自blog.csdn.net/weixin_43521836/article/details/89637870
今日推荐