题目: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;
}