$NOIP2012$ 题解报告

目录

$Luogu\ P1079$ $Vigenère$密码$(\ √\ )$

$Luogu\ P1080$ 国王游戏$(\ √\ )$

$Luogu\ P1081$ 开车旅行( )

$Luogu\ P1082$ 同余方程$(\ √\ )$

$Luogu\ P1083$ 借教室$(\ √\ )$

$Luogu\ P1084$ 疫情控制$(\ √\ )$


 

$Luogu\ P1079$ $Vigenère$密码

题目传送门

很水的模拟题,注意看清题目!

 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 char k[102],s1[1002],s2[1002];
19 int n,m,add='a'-'A';
20 il char cal(char x,char y){
21     bool type=0;char ans;
22     //cout<<"x="<<x<<" y="<<y<<endl;
23     int X,Y;
24     if(y>='a'&&y<='z')type=1,Y=y-add-'A';
25     else Y=y-'A';
26     if(x>='a'&&x<='z')X=x-add-'A';
27     else X=x-'A';
28     //cout<<"X="<<X<<" Y="<<Y<<endl;
29     if(type)ans=(char)(Y-X+26)%26+add+'A';
30     else ans=(char)(Y-X+26)%26+'A';
31     //while(ans<0)ans+=26;
32     //cout<<"ans="<<ans<<endl;
33     return ans;
34 }
35 int main(){
36     freopen("1.in","r",stdin);
37     freopen("1.out","w",stdout);
38     scanf("%s",k);n=strlen(k);
39     scanf("%s",s1);m=strlen(s1);
40     //cout<<"A="<<(int)'A'<<" a="<<(int)'a'<<" add="<<add<<endl;
41     //char c=(char)87;cout<<"c="<<c<<endl;
42     go(i,0,m-1)s2[i]=cal(k[i%n],s1[i]);
43     go(i,0,m-1)pf("%c",s2[i]);puts("");
44     return 0;
45 }
代码戳这里

 


 

$Luogu\ P1080$ 国王游戏

题目传送门

贪心经典例题,注意是根据什么排序的

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 inline int read()
  4 {
  5     int ret=0,f=1;
  6     char ch=getchar();
  7     while(ch>'9'||ch<'0')
  8     {
  9         if(ch=='-')
 10             f=-1;
 11         ch=getchar();
 12     }
 13     while(ch>='0'&&ch<='9')
 14     {
 15         ret=(ret<<1)+(ret<<3)+ch-'0';
 16         ch=getchar();
 17     }
 18     return ret*f;
 19 }
 20 int n,lens=1,lenm=1,lena=1,sum[10005]={0,1},maxn[10005]={0,1},ans[10005];
 21 struct node
 22 {
 23     int a;
 24     int b;
 25 }s[1005];
 26 inline bool cmp(node x,node y)
 27 {
 28     return x.a*x.b<y.a*y.b;
 29 }
 30 inline void mul(int x)
 31 {
 32     int tmp=0;
 33     for(register int i=1;i<=lens;i++)
 34         sum[i]*=x;
 35     for(register int i=1;i<=lens;i++)
 36     {
 37         tmp+=sum[i];
 38         sum[i]=tmp%10;
 39         tmp/=10;
 40     }
 41     while(tmp)
 42     {
 43         lens++;
 44         sum[lens]=tmp%10;
 45         tmp/=10;
 46     }
 47 }
 48 inline void div(int x)
 49 {
 50     memset(ans,0,sizeof(ans));
 51     lena=lens;
 52     int tmp=0;
 53     for(register int i=lena;i;i--)
 54     {
 55         tmp*=10;
 56         tmp+=sum[i];
 57         if(tmp>=x)
 58         {
 59             ans[i]=tmp/x;
 60             tmp%=x;
 61         }
 62     }
 63     while(ans[lena]==0)
 64     {
 65         if(lena==1)
 66             break;
 67         lena--;
 68     }
 69 }
 70 inline void cmp1()
 71 {
 72     if(lena>lenm)
 73     {
 74         for(register int i=1;i<=lena;i++)
 75             maxn[i]=ans[i];
 76         lenm=lena;
 77     }
 78     else if(lenm==lena)
 79     {
 80         for(register int i=lena;i;i--)
 81         {
 82             if(maxn[i]<ans[i])
 83             {
 84                 for(register int j=1;j<=lena;j++)
 85                     maxn[j]=ans[j];
 86                 lenm=lena;
 87                 break;
 88             }
 89         }
 90     }
 91 }
 92 inline void write()
 93 {
 94     for(register int i=lenm;i;i--)
 95         printf("%d",maxn[i]);
 96 }
 97 int main()
 98 {
 99     n=read();
100     s[0].a=read();
101     s[0].b=read();
102     for(register int i=1;i<=n;i++)
103     {
104         s[i].a=read();
105         s[i].b=read();
106     }
107     sort(s+1,s+n+1,cmp);
108     for(register int i=1;i<=n;i++)
109     {
110         mul(s[i-1].a);
111         div(s[i].b);
112         cmp1();
113     }
114     write();
115     return 0;
116 }
代码戳这里

 


 

$Luogu\ P1081$ 开车旅行

题目传送门

之前写过一篇题解,贴个$link\to$戳这里

代码还没过$QAQ$


 

$Luogu\ P1082$ 同余方程

题目传送门

扩展欧几里得模板

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 ll a,b,x,y;
 5 ll exgcd(ll a,ll b,ll &x,ll &y){
 6     if(!b) {x=1;y=0;return a;}
 7     ll d=exgcd(b,a%b,x,y);
 8     ll z=x;x=y;y=z-y*(a/b);
 9     return d;
10 }
11 int main(){
12     cin>>a>>b;
13     ll ans=exgcd(a,b,x,y);
14     cout<<(x%b+b)%b<<endl;
15     return 0;
16 }
代码戳这里

 


 

$Luogu\ P1083$ 借教室

题目传送门

线段树大法好

直接线段树……挺板子的?

 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=1e6+2;
19 int n,m,a[N];
20 struct Tree{
21     int l,r,tag,mn;
22 }t[N<<2];
23 il void build(ri p,ri l,ri r){
24     if(l>r)return;
25     if(l==r){t[p]=(Tree){l,r,0,a[l]};return;}
26     ri mid=(l+r)>>1;
27     build(p<<1,l,mid);build((p<<1)+1,mid+1,r);
28     t[p]=(Tree){l,r,0,min(t[p<<1].mn,t[(p<<1)+1].mn)};
29     return;
30 }
31 il void push(ri p){
32     if(t[p].tag==0)return;
33     t[p<<1].mn-=t[p].tag;t[p<<1|1].mn-=t[p].tag;
34     t[p<<1].tag+=t[p].tag;t[(p<<1)+1].tag+=t[p].tag;
35     t[p].tag=0;return;
36 }
37 il bool change(ri p,ri l,ri r,ri d){
38     if(l<=t[p].l&&r>=t[p].r){
39         if(t[p].mn<d)return 0;
40         t[p].tag+=d;t[p].mn-=d;return 1;
41     }
42     ri mid=(t[p].l+t[p].r)>>1;push(p);
43     bool ans=1;
44     if(l<=mid)ans&=change(p<<1,l,r,d);
45     if(r>mid)ans&=change((p<<1)+1,l,r,d);
46     t[p].mn=min(t[p<<1|1].mn,t[p<<1].mn);
47     return ans;
48 }
49 int main(){
50     n=fr();m=fr();
51     go(i,1,n)a[i]=fr();
52     build(1,1,n);
53     go(i,1,m){
54         ri d=fr(),l=fr(),r=fr();
55         if(!change(1,l,r,d)){puts("-1");pf("%d\n",i);return 0;}
56     }
57     puts("0");return 0;
58 }
代码戳这里

我考虑什么时候再写个二分的做法叭


 

$Luogu\ P1084$ 疫情控制

题目传送门

为什么大家都觉得这题挺难写昂?我感觉我没调好久$QAQ$

首先最优的显然是每个军队都走到能走到的深度最小的节点,然后如果有军队可以走到根节点,就先停在根节点的子节点。然后我们再扫描根节点的所有子节点中有哪些是到叶子节点的路径还没有驻扎军队的,用那些可以到根节点的军队与这些根节点的子节点去匹配即可

代码确实有点难写

  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 #define P pair<ll,int>
 14 #define mp make_pair
 15 using namespace std;
 16 il int fr(){
 17     ri w=0,q=1;char ch=g();
 18     while(ch<'0'||ch>'9'){if(ch=='-')q=-1;ch=g();}
 19     while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=g();
 20     return w*q;
 21 }
 22 const int N=50002;
 23 int n,m,ed,hd[N],f[N][20],dep[N],army[N],son;
 24 ll dis[N],r,l,ans;
 25 bool v[N],as;
 26 priority_queue<ll>q1,q2;
 27 struct edge{
 28     int nxt,to,w;
 29 }e[N<<1];
 30 il void build(int u,int v,int w){e[++ed]=(edge){hd[u],v,w};hd[u]=ed;return;}
 31 il void Tree(int x,int fa){
 32     dep[x]=dep[fa]+1;f[x][0]=fa;
 33     go(i,1,19)f[x][i]=f[f[x][i-1]][i-1];
 34     E(i,x){
 35         if(t(i)==fa)continue;
 36         if(x==1)son++;
 37         dis[t(i)]=dis[x]+e[i].w;Tree(t(i),x);
 38     }
 39     return;
 40 }
 41 il bool dfs(int x,int fa){
 42     if(v[x])return 1;
 43     bool fin=0;
 44     E(i,x){
 45         if(t(i)==fa)continue;
 46         fin=1;
 47         if(!dfs(t(i),x))return 0;
 48     }
 49     if(fin)return 1;
 50     return 0;
 51 }
 52 il bool check(ll x){
 53     //cout<<"mid="<<x<<endl;
 54     while(!q1.empty())q1.pop();
 55     while(!q2.empty())q2.pop();mem(v,0);
 56     P a[N];int tot=0;bool b[N];mem(b,0);
 57     go(i,1,m){
 58         int A=army[i];ll nw=x;
 59         //cout<<"x="<<A<<endl;
 60         back(j,19,0)if(dep[f[A][j]]>dep[1]&&(dis[A]-dis[f[A][j]])<=nw)
 61             nw-=(dis[A]-dis[f[A][j]]),A=f[A][j];
 62         //cout<<"x'="<<A<<endl;
 63         if(nw>dis[A]&&f[A][0]==1)a[++tot]=mp(nw-dis[A],A);
 64         else v[A]=1;
 65     }
 66     E(i,1)if(!dfs(t(i),1))b[t(i)]=1;
 67     sort(a+1,a+1+tot);
 68     go(i,1,tot)
 69         if(b[a[i].second]&&a[i].first<dis[a[i].second])b[a[i].second]=0;
 70         else q1.push(-a[i].first);
 71     E(i,1)if(b[t(i)])q2.push(-dis[t(i)]);
 72     if((int)q1.size()<(int)q2.size())return 0;
 73     while((!q2.empty())&&(!q1.empty())){
 74         ll d1=-q1.top();q1.pop();
 75         ll d2=-q2.top();if(d1>=d2)q2.pop();
 76     }
 77     if(q1.empty()&&(!q2.empty()))return 0;
 78     else return 1;
 79 }
 80 int main(){
 81     //freopen("1.in","r",stdin);
 82     //freopen("1.out","w",stdout);
 83     n=fr();
 84     go(i,1,n-1){
 85         int u=fr(),v=fr(),w=fr();r+=w;
 86         build(u,v,w);build(v,u,w);
 87     }
 88     Tree(1,0);m=fr();
 89     go(i,1,m){
 90         int x=fr();
 91         v[x]=1;army[i]=x;
 92     }
 93     if(son>m){puts("-1");return 0;}
 94     while(l<=r){
 95         ll mid=(l+r)>>1;
 96         //cout<<"l="<<l<<" r="<<r<<" mid="<<mid<<endl;
 97         if(check(mid))r=mid-1,ans=mid,as=1;
 98         else l=mid+1;
 99     }
100     if(as)pf("%lld\n",ans);
101     else puts("-1");
102     return 0;
103 }
代码戳这里

 

posted @ 2019-11-05 17:07  小叽居biubiu  阅读(188)  评论(2编辑  收藏  举报