$NOIP2009$ 题解报告
目录
•$Luogu\ P1071$ 潜伏者$(\ √\ )$
•$Luogu\ P1072$ $Hankson$的趣味题$(\ √\ )$
•$Luogu\ P1073$ 最优贸易$(\ √\ )$
•$Luogu\ P1074$ 靶形数独$(\ √\ )$
$Luogu\ P1071$ 潜伏者
题目很水,直接模拟即可,注意一下细节
1 #include<bits/stdc++.h> 2 using namespace std; 3 string x,y,z; 4 int sum[27],tot=0; 5 bool b1[27],b2[27]; 6 int main(){ 7 cin>>x>>y>>z; 8 for(int i=0;i<x.size();++i) 9 { 10 if(!b1[x[i]-'A'+1]&&!b2[y[i]-'A'+1]) 11 { 12 sum[x[i]-'A'+1]=y[i]; 13 b1[x[i]-'A'+1]=b2[y[i]-'A'+1]=true; 14 ++tot; 15 } 16 else if(sum[x[i]-'A'+1]!=y[i]) 17 { 18 cout<<"Failed"; 19 return 0; 20 } 21 } 22 if(tot!=26) 23 { 24 cout<<"Failed"; 25 return 0; 26 } 27 for(int i=0;i<z.size();++i) 28 { 29 printf("%c",sum[z[i]-'A'+1]); 30 } 31 }
$Luogu\ P1072$ $Hankson$的趣味题
这题有个很好的性质昂
$gcd(x,a0)=a1\to gcd(x/a1,a0/a1)=1$,因为挺显然的我就不证了
然后我们就可以想到,由于$lcm(x,b0)=b1$,所以可得$gcd(b1/x,b1/b0)=1$
所以可以看出来$x$是$b1$的约数且是$a1$的倍数,并且满足$gcd(x/a1,a0/a1)=1,gcd(b1/x,b1/b0)=1$
我们就$\sqrt{b1}$地枚举$b1$的约数,判断是否满足条件即可
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 using namespace std; 11 il int fr(){ 12 ri w=0,q=1;char ch=g(); 13 while(ch<'0'||ch>'9'){if(ch=='-')q=-1;ch=g();} 14 while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=g(); 15 return w*q; 16 } 17 int n,a0,a1,b0,b1,ans; 18 il int gcd(ri x,ri y){return y==0?x:gcd(y,x%y);} 19 int main(){ 20 //freopen(".in","r",stdin); 21 //freopen(".out","w",stdout); 22 n=fr(); 23 while(n--){ 24 a0=fr();a1=fr();b0=fr();b1=fr();ans=0; 25 ri a2=a0/a1,b2=b1/b0,sqt=(int)sqrt(b1); 26 go(i,1,sqt){ 27 if(b1%i)continue; 28 if(i%a1==0&&gcd(i/a1,a2)==1&&gcd(b1/i,b2)==1)ans++; 29 ri x=b1/i;if(x==i)continue; 30 if(x%a1==0&&gcd(x/a1,a2)==1&&gcd(b1/x,b2)==1)ans++; 31 32 } 33 pf("%d\n",ans); 34 } 35 return 0; 36 }
$Luogu\ P1073$ 最优贸易
在题解区看到一个不错的做法$($其实就是第一个$)$
设$f[x]$表示从起点到$x$的最大差价,$mn[x]$记录从起点到$x$的路径上的最小值
我们从$1$号点开始暴力走,每次记录并更新,如果没有更新的话就退出。$emmmm$差不多就这样好像有点口糊
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 #define E(i,x) for(ri i=hd[x];i;i=e[i].nxt) 12 #define t(i) e[i].to 13 using namespace std; 14 il int fr(){ 15 ri w=0,q=1;char ch=g(); 16 while(ch<'0'||ch>'9'){if(ch=='-')q=-1;ch=g();} 17 while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=g(); 18 return w*q; 19 } 20 const int N=100002; 21 const int M=500002; 22 int n,m,hd[N],p[N],mn[N],f[N],ed; 23 struct edge{ 24 int nxt,to; 25 }e[M]; 26 il void build(ri x,ri y,ri z){ 27 e[++ed]=(edge){hd[x],y};hd[x]=ed; 28 if(z==1)return;swap(x,y); 29 e[++ed]=(edge){hd[x],y};hd[x]=ed; 30 return; 31 } 32 il void work(ri x,ri Min,ri frm){ 33 bool tag=1; 34 Min=min(Min,p[x]); 35 if(mn[x]>Min)tag=0,mn[x]=Min; 36 ri mx=max(f[frm],p[x]-Min); 37 if(mx>f[x])tag=0,f[x]=mx; 38 if(tag)return; 39 E(i,x)work(t(i),Min,x); 40 return; 41 } 42 int main(){ 43 //freopen(".in","r",stdin); 44 //freopen(".out","w",stdout); 45 n=fr();m=fr();mem(mn,0x3f); 46 go(i,1,n)p[i]=fr(); 47 go(i,1,m){ 48 ri x=fr(),y=fr(),z=fr(); 49 build(x,y,z); 50 } 51 work(1,p[1],0); 52 pf("%d\n",f[n]); 53 return 0; 54 }
$Luogu\ P1074$ 靶形数独
垃圾题目卡我代码
暴力枚举就好了$QwQ$,注意有个优化就是我们按照每行的$0$的数量从小到大搜索,这样就不会$TLE$
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 int d[85],ans=-1,a[10][10],as[10][10]; 19 bool vis[3][10][10]; 20 struct node{ 21 int line,sum; 22 }l[10]; 23 il bool cmp(node x,node y){return x.sum<y.sum;} 24 il int find(ri x,ri y){ 25 if(x<=3){ 26 if(y<=3)return 1; 27 else 28 if(y<=6)return 2; 29 else return 3; 30 } 31 else{ 32 if(x<=6){ 33 if(y<=3)return 4; 34 else 35 if(y<=6)return 5; 36 else return 6; 37 } 38 else{ 39 if(y<=3)return 7; 40 else 41 if(y<=6)return 8; 42 else return 9; 43 } 44 } 45 } 46 il int score(ri x,ri y){ 47 if(x==1||x==9||y==1||y==9)return 6; 48 if(x==2||x==8||y==2||y==8)return 7; 49 if(x==3||x==7||y==3||y==7)return 8; 50 if(x==4||x==6||y==4||y==6)return 9; 51 return 10; 52 } 53 il int cal(){ 54 ri As=0; 55 go(i,1,9)go(j,1,9)As+=as[i][j]*score(i,j); 56 return As; 57 } 58 il void work(ri id){ 59 if(id>81){ans=max(ans,cal());return;} 60 ri x=d[id]/9+1,y=d[id]%9; 61 if(y==0)x--,y=9; 62 if(a[x][y]){as[x][y]=a[x][y];work(id+1);return;} 63 go(i,1,9){ 64 if(vis[0][x][i]||vis[1][y][i]||vis[2][find(x,y)][i])continue; 65 vis[0][x][i]=vis[1][y][i]=vis[2][find(x,y)][i]=1; 66 as[x][y]=i;work(id+1); 67 vis[0][x][i]=vis[1][y][i]=vis[2][find(x,y)][i]=0; 68 } 69 return; 70 } 71 int main(){ 72 go(i,1,9){ 73 ri sum=0; 74 go(j,1,9){ 75 a[i][j]=fr(); 76 if(a[i][j]==0)sum++; 77 else vis[0][i][a[i][j]]=vis[1][j][a[i][j]]=vis[2][find(i,j)][a[i][j]]=1; 78 } 79 l[i]=(node){i,sum}; 80 } 81 sort(l+1,l+10,cmp); 82 ri num=0; 83 go(i,1,9)go(j,1,9){ 84 ri x=9*(l[i].line-1)+j; 85 d[++num]=x; 86 } 87 work(1);pf("%d\n",ans); 88 return 0; 89 }