题面..复制不过来..去BZOJ上看吧QwQ。
原题地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3109
思路&&分析:
Emmm…这题其实没啥好讲的,只要有信仰打暴力打上去就能A了..只是需要加一点剪枝,就是每一行的最后一个可以根据前8个数的和算出而不需要1~9扫一遍,每一列的最后一个和每一块的最后一个也都是一样的,只要加了这三个剪枝就可以稳过了。
Code
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
bool Finish_read;
template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}
template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}
template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');}
template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}
/*================Header Template==============*/
int ans[9][9],sum[9],row[9],col[9],liml[9][9],limr[9][9],line[9]={1,3,5,6,8,10,11,13,15},cnt=9,posi[6]={1,2,4,5,7,8},cnt2;
bool usec[9][10],user[9][10],uses[9][10],bigr[9][9],bigc[9][9];
inline int nxtx(int x,int y) {
if(y==8)
return x+1;
return x;
}
inline int nxty(int x,int y) {
if(y==8)
return 0;
return y+1;
}
inline void writeit() {
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
printf("%d%c",ans[i][j],j==8?'\n':' ');
}
inline bool check() {
// writeit();
for(int i=0;i<9;i++)
for(int j=0;j<9;j++) {
if(i%3!=2)
if(bigr[i][j]!=(ans[i][j]>ans[i+1][j]))
return 0;
if(j%3!=2)
if(bigc[i][j]!=(ans[i][j]>ans[i][j+1]))
return 0;
}
return 1;
}
inline void dfs(int x,int y) {
int b=(x/3)*3+(y/3);
// cerr<<x<<" ."<<y<<" "<<sum[b]<<" "<<col[x]<<" "<<row[y]<<endl;
// writeit();
if(x==9&&y==0) {
// if(check()) {
writeit();
exit(0);
// }
}
if(x%3==2&&y%3==2) {
int i=45-sum[b];
if(!usec[x][i]&&!user[y][i]&&!uses[b][i]) {
if(x%3&&bigr[x][y]!=(i>ans[x-1][y]))
return;
if(y%3&&bigc[x][y]!=(i>ans[x][y-1]))
return;
usec[x][i]=user[y][i]=uses[b][i]=1;
sum[b]+=i;row[y]+=i;col[x]+=i;ans[x][y]=i;
dfs(nxtx(x,y),nxty(x,y));
sum[b]-=i;row[y]-=i;col[x]-=i;ans[x][y]=0;
usec[x][i]=user[y][i]=uses[b][i]=0;
}
return;
}
if(y==8) {
int i=45-col[x];
if(!usec[x][i]&&!user[y][i]&&!uses[b][i]) {
if(x%3&&bigr[x][y]!=(i>ans[x-1][y]))
return;
if(y%3&&bigc[x][y]!=(i>ans[x][y-1]))
return;
usec[x][i]=user[y][i]=uses[b][i]=1;
sum[b]+=i;row[y]+=i;col[x]+=i;ans[x][y]=i;
dfs(nxtx(x,y),nxty(x,y));
sum[b]-=i;row[y]-=i;col[x]-=i;ans[x][y]=0;
usec[x][i]=user[y][i]=uses[b][i]=0;
}
return;
}
if(x==8) {
int i=45-row[y];
if(!usec[x][i]&&!user[y][i]&&!uses[b][i]) {
if(x%3&&bigr[x][y]!=(i>ans[x-1][y]))
return;
if(y%3&&bigc[x][y]!=(i>ans[x][y-1]))
return;
usec[x][i]=user[y][i]=uses[b][i]=1;
sum[b]+=i;row[y]+=i;col[x]+=i;ans[x][y]=i;
dfs(nxtx(x,y),nxty(x,y));
sum[b]-=i;row[y]-=i;col[x]-=i;ans[x][y]=0;
usec[x][i]=user[y][i]=uses[b][i]=0;
}
return;
}
for(int i=1;i<=9;i++) {
if(!usec[x][i]&&!user[y][i]&&!uses[b][i]&&sum[b]+i<=45&&row[y]+i<=45&&col[x]+i<=45) {
if(x%3&&bigr[x][y]!=(i>ans[x-1][y]))
continue;
if(y%3&&bigc[x][y]!=(i>ans[x][y-1]))
continue;
usec[x][i]=user[y][i]=uses[b][i]=1;
sum[b]+=i;row[y]+=i;col[x]+=i;ans[x][y]=i;
dfs(nxtx(x,y),nxty(x,y));
sum[b]-=i;row[y]-=i;col[x]-=i;ans[x][y]=0;
usec[x][i]=user[y][i]=uses[b][i]=0;
}
}
}
int main() {
// freopen("input.txt","r",stdin);
// freopen("check.out","w",stdout);
for(int i=1;i<=15;i++) {
char op[2];int pos=lower_bound(line,line+cnt,i)-line;
if(line[pos]==i) {
for(int j=0;j<6;j++) {
scanf("%s",op);
if(op[0]=='<')
bigc[pos][posi[j]]=1;
else
bigc[pos][posi[j]]=0;
}
}
else {
for(int j=0;j<9;j++) {
scanf("%s",op);
if(op[0]=='^')
bigr[posi[cnt2]][j]=1;
else
bigr[posi[cnt2]][j]=0;
}
cnt2++;
}
}
// for(int i=0;i<9;i++)
// for(int j=0;j<9;j++)
// printf("%c%c",j%3==0?' ':!bigc[i][j]?'>':'<',j==8?'\n':' ');
// cout<<"========================="<<endl;
// for(int i=0;i<9;i++)
// for(int j=0;j<9;j++)
// printf("%c%c",i%3==0?' ':!bigr[i][j]?'v':'^',j==8?'\n':' ');
// cout<<"========================="<<endl;
dfs(0,0);
}