$NOIP1997$ 题解报告

就只有一道题$QwQ$

$Luogu\ P1549$ 棋盘问题

题目传送门

就……暴搜可以过。线性筛预处理出质数,然后枚举每个位置填哪个数,判断一下是否合法。注意一下搜索策略,因为保证第一行和第一列的所有数之和最小,则使其他地方的数尽量大,即第一行和第一列从小到大枚举,其他位置从大到小枚举。

 1 #include<bits/stdc++.h>
 2 #define ri register int
 3 #define ll long long
 4 #define rl register ll
 5 #define go(i,a,b) for(ri i=a;i<=b;i++)
 6 #define back(i,a,b) for(ri i=a;i>=b;i--)
 7 #define g() getchar()
 8 #define il inline
 9 #define pf printf
10 #define mem(a,b) memset(a,b,sizeof(a))
11 using namespace std;
12 il int fr(){
13     ri w=0,q=1;char ch=g();
14     while(ch<'0'||ch>'9'){if(ch=='-')q=-1;ch=g();}
15     while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=g();
16     return w*q;
17 }
18 const int N=102;
19 int n,m,v[N],prim[N],num,a[12][12];
20 bool vis[N],ans=0;
21 il void ready(){
22     go(i,2,m<<1){
23         if(!v[i])v[i]=i,prim[++num]=i;
24         go(j,1,num){
25             if(i*prim[j]>(m<<1)||prim[j]>v[i])break;
26             v[i*prim[j]]=prim[j];
27         }
28     }
29     return;
30 }
31 il void work(ri x,ri y){
32     if(x==1||y==1){
33         go(i,2,m){
34             if(ans)return;
35             if(vis[i])continue;
36             /*cout<<"x="<<x<<" y="<<y<<" "<<i<<endl;
37             if(x>1)cout<<"h="<<a[x-1][y]+i<<endl;
38             if(y>1)cout<<"l="<<a[x][y-1]+i<<endl;*/
39             if(x>1&&v[a[x-1][y]+i]!=a[x-1][y]+i)continue;
40             if(y>1&&v[a[x][y-1]+i]!=a[x][y-1]+i)continue;
41             vis[i]=1,a[x][y]=i;
42             if(y==n)work(x+1,1);
43             else work(x,y+1);
44             vis[i]=0;
45         }
46     }
47     else{
48         back(i,m,2){
49             if(ans)return;
50             if(vis[i])continue;
51             /*cout<<"x="<<x<<" y="<<y<<" "<<i<<endl;
52             if(x>1)cout<<"h="<<a[x-1][y]+i<<endl;
53             if(y>1)cout<<"l="<<a[x][y-1]+i<<endl;*/
54             if(v[a[x-1][y]+i]!=a[x-1][y]+i)continue;
55             if(v[a[x][y-1]+i]!=a[x][y-1]+i)continue;
56             vis[i]=1,a[x][y]=i;
57             if(x==n&&y==n){ans=1;return;}
58             if(y==n)work(x+1,1);
59             else work(x,y+1);
60             vis[i]=0;
61         }
62     }
63     return;
64 }
65 int main(){
66     //freopen(".in","r",stdin);
67     //freopen(".out","w",stdout);
68     n=fr();m=n*n;ready();
69     a[1][1]=1;work(1,2);
70     if(!ans)puts("NO");
71     else{go(i,1,n){go(j,1,n)pf("%d ",a[i][j]);puts("");}}
72     return 0;
73 }
代码戳这里

 

posted @ 2019-10-29 21:37  小叽居biubiu  阅读(124)  评论(0编辑  收藏  举报