uva11625 Lines of Containers

wa!   wa!    wa!   wa!    wa!   wa!    wa!   wa!    

日常赛第四水题,然后wa了两小时。

我的思路是没错的,贪心交换,每次把某一列交换到它规定的位置,能保证最小交换次数,

但是怎样判断什么·时候输出*好呢?

写了多个特判,最终卡死在test12.

判断方法是这样的:

把任意一行和一列还原好,再遍历整个行列式,如果此时仍然有位置不对,就输出*,

仔细想想,当我们把一个行列式的行与行,列与列两两交换,无论我们我们这么交换,一行/列中的元素始终在同一行/列,只是打乱的顺序而已,

所以当你把任意一行和一列还原后,其他行和列收到约束,自然会还原,如果玩过魔方应该能理解

明白这些后只要模拟交换过程+贪心还原就好了。。。。。。

所以是水题了

ac代码:

#include<iostream>
#include<map>
#include<algorithm>
#include<string>
#include<cstdio>
#include<vector>
#include<functional>
#include<set>
#include<string>
using namespace std;
#define ll long long
#define kg " "
int mp[400][400];
int l,c,cnt;
void swapc(int c1,int c2){
int t;
for(int i=1;i<=l;i++){
t=mp[i][c1];
mp[i][c1]=mp[i][c2];
mp[i][c2]=t;
}
}
void swapl(int l1,int l2){
int t;
for(int i=1;i<=c;i++){
t=mp[l1][i];
mp[l1][i]=mp[l2][i];
mp[l2][i]=t;
}
}
bool istrue(){
int l1=0;int c1=0;
for(int i=1;i<=l;i++){
for(int j=1;j<=c;j++){
if(mp[i][j]==1){
l1=i;
c1=j;
break;
}
}
}
if(l1==0||c1==0){
return false;
}
if(l1!=1){
swapl(l1,1);cnt++;
}
if(c1!=1){
swapc(c1,1);cnt++;
}

int k=0;
for(int i=2;i<=c;i++){
k=0;
for(int j=i;j<=c;j++){
if(mp[1][j]==i){
k=j;break;
}
}
if(k==0)return false;
if(i!=k){
swapc(k,i);cnt++;
}
}
for(int i=1;i<=l;i++){
k=0;
for(int j=i;j<=l;j++){
if(mp[j][1]==i*c-c+1){
k=j;break;
}
}
if(k==0)return false;
if(k!=i){
swapl(k,i);cnt++;
}
}
k=1;
for(int i=1;i<=l;i++){
for(int j=1;j<=c;j++){
if(mp[i][j]!=k++){
return false;
}
}
}
return true;
}
int main(){
cin>>l>>c;
for(int i=1;i<=l;i++){
for(int j=1;j<=c;j++){
cin>>mp[i][j];
}
}
if(istrue()){
cout<<cnt<<endl;
}
else{
cout<<"*"<<endl;
}
return 0;
}

posted @ 2017-12-10 13:13  DNoSay  阅读(181)  评论(0编辑  收藏  举报