[2016/7/11][usaco 2.1]Sorting a Three-Valued Sequence

来源:互联网 发布:qq刷红包 源码 编辑:程序博客网 时间:2024/09/21 06:19

题目:http://train.usaco.org/usacoprob2?a=SYDSnPU3bU7&S=sort3

题目大意:给你一个数串,其中元素从{1,2,3}中选出,问最少把其中元素两两互换几次,才能得到一个非降序数串。


再次1A!果然在城堡用完的人品下午又回来了啊哈哈哈

刚开始看到这题简直不会。。都想直接看题解了。最后抑制了自己懒惰max的内心,老老实实在纸上画图。

先确定的是一定要sort一遍,再把原来的顺序和sort后的相比较。那么如何确定该换哪两个呢?

第一步:目的是换一次让两个元素都回归正确位置。可以先扫一遍,把位置不用换的mark一下。

第二步:目的是把剩下的元素都解决了。这次换一次最少只能让一个元素归位。

(所以这其实就是一道简单题啊喂!!期初还联想到了快排,丢过去丢回来,结果可以这样做,但是这一步完全没必要,bug频出效率也不见得高了多少。。把函数注释掉了)

代码:

/* ID: 49743541 PROG: sort3 LANG: C++ */#include <stdio.h>#include <algorithm>using namespace std;int N;int a[1004];int b[1004];int mark[1004];int begin[4];int end[4];int flag[1004];int ccount;void dfs(int i){//这就是那个没有什么卵用的函数 if(flag[i]) return;flag[i];bool A = 0;bool B = 0;if(a[i]==3&&i!=N){for(int j = N;j>=i;j--){if(b[j]!=3||A)break;for(int k = 1;k<=j;k++){if(b[k]==3){A = 1;continue;} if(a[k]==3&&b[k]==a[j]){swap(a[j],a[k]); mark[j] = 1;mark[k] = 1;ccount++;dfs(j); break;}}}}else if(a[i]==1&&i!=1){for(int j = 1;j<=i;j++){//在1左边且大于1 if(b[j]!=1||B) break;for(int k = j+1;k<=N;k++){if(b[k]==1){B = 1;continue;} if(a[k]==1&&b[k]==a[j]){swap(a[j],a[k]);mark[j] = 1;mark[k] = 1;ccount++;dfs(j); break;}}}}}int main(){freopen("sort3.in","r",stdin);freopen("sort3.out","w",stdout);scanf("%d",&N);for(int i = 1;i<=N;i++){scanf("%d",&a[i]);b[i] = a[i];}sort(b+1,b+N+1);int p = 0;int i;for(i = 1;i<N;i++){if(a[i]==b[i]) mark[i] = true;}if(a[i]==b[i])  mark[i] = true;//printf("23333333");//for(int i = N;i>=1;i--)//if(mark[i]) dfs(i);//printf("233333333");for(int i = 1;i<=N;i++){if(!mark[i]){for(int j = i+1;j<=N;j++){if(a[i]==b[j]&&a[j]==b[i]&&(!mark[j])){swap(a[i],a[j]);mark[i] = 1;mark[j] = 1;ccount++;break;}}}}int shu = 0;//printf("23333");while(shu!=N){for(int i = 1;i<=N;i++){if(!mark[i]){for(int j = i+1;j<=N;j++){if(a[j]==b[i]&&(!mark[j])){if(a[i]==b[j]){swap(a[i],a[j]);mark[i] = 1;mark[j] = 1;ccount++;shu++;break;}else{swap(a[i],a[j]);mark[i] = 1;ccount++;shu++;break;}}}}else shu++;}if(shu<N) shu=0;}printf("%d\n",ccount);/*for(int i = 1;i<=N;i++) printf("%d ",a[i]);printf("\n");for(int j = 1;j<=N;j++)printf("%d ",b[j]);*/return 0;}



0 0
原创粉丝点击