$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 }
代码戳这里

 

posted @ 2019-10-26 09:20  小叽居biubiu  阅读(160)  评论(0编辑  收藏  举报