作为提高组的题,肯定不能像普及组那样一句话题解了。
D1T1——生活大爆炸版石头剪刀布——打个表模拟(好吧,还真是一句话)
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; inline int read(){ int t=1,num=0;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();} while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();} return num*t; } const int f[5][5]={ {0,0,1,1,0}, {1,0,0,1,0}, {0,1,0,0,1}, {0,0,1,0,1}, {1,1,0,0,0} }; int n,na,nb,a[210],b[210],ansa=0,ansb=0; int main() { n=read();na=read();nb=read(); for(int i=0;i<na;i++)a[i]=read(); for(int i=0;i<nb;i++)b[i]=read(); for(int i=0;i<n;i++){ int x=a[i%na],y=b[i%nb]; ansa+=f[x][y];ansb+=f[y][x]; } printf("%d %d",ansa,ansb); return 0; }
D1T2——联合权值
枚举每个点,只有与它连接的不同的两点对答案有贡献。
这里有一个数学方法,是个很好的优化:
(a+b)^2-a^2-b^2=2ab,(a+b+c)^2-a^2-b^2-c^2=2ab+2ac+2bc,,,,,,,,,
这样就可以简便的求出答案。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<vector> #include<queue> using namespace std; inline int read(){ int t=1,num=0;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();} while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();} return num*t; } const int maxn=200010,mod=10007; inline int max(int a,int b){return a>b?a:b;} vector<int> g[maxn]; int w[maxn],n,ans,sum; int main() { n=read(); for(int i=1;i<n;i++){ int x=read(),y=read(); g[x].push_back(y);g[y].push_back(x); } for(int i=1;i<=n;i++)w[i]=read(); for(int i=1;i<=n;i++){ int len=g[i].size(); if(len<2)continue; int fi=0,se=0,he1=0,he2=0; for(int j=0;j<len;j++){ int x=g[i][j]; if(w[x]>se) if(w[x]>fi)se=fi,fi=w[x]; else se=w[x]; he1+=w[x];he1%=mod; he2+=w[x]*w[x];he2%=mod; } ans=max(ans,fi*se); sum+=he1*he1-he2;sum%=mod; } printf("%d %d",ans,sum); return 0; }
D1T3——飞扬的小鸟
可真是丧,据说和愤怒的小鸟是cp。
对于上升,我们用完全背包的做法,对于下降,用01背包,超出m的高度特判一下。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; inline int read(){ int t=1,num=0;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();} while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();} return num*t; } const int N=10010,M=1010,INF=1e9; int n,m,k,up[N],down[N],g[M],f[M],ans=0,t=1; struct sg{int p,l,h;}s[N]; bool cmp(sg a,sg b){return a.p<b.p;} inline int min(int a,int b){return a<b?a:b;} int main() { n=read();m=read();k=read(); for(int i=1;i<=n;i++)up[i]=read(),down[i]=read(); for(int i=1;i<=k;i++) s[i].p=read(),s[i].l=read(),s[i].h=read(); sort(s+1,s+1+k,cmp); for(int i=1;i<=n;i++){ for(int j=0;j<=m;j++) g[j]=f[j],f[j]=INF; int have=0,pass=0; if(i-1==s[t].p&&t!=k+1)have=1; for(int j=1;j<=m;j++){ if(j-up[i]>0){ if((!have)||(j-up[i]>s[t].l&&j-up[i]<s[t].h)) f[j]=min(f[j],g[j-up[i]]+1); f[j]=min(f[j],f[j-up[i]]+1); if(f[j]!=INF)pass=1; } if(j+up[i]>m){ if((!have)||(j>s[t].l&&j<s[t].h)) f[m]=min(f[m],g[j]+1); f[m]=min(f[m],f[j]+1); if(f[m]!=INF)pass=1; } } for(int j=m-down[i];j>=1;j--){ if((!have)||(j+down[i]>s[t].l&&j+down[i]<s[t].h)) f[j]=min(f[j],g[j+down[i]]); if(f[j]!=INF)pass=1; } if(have){ if(t<=k)t++; if(pass)ans++; else{printf("0\n%d",ans);return 0;} } } ans=INF; for(int i=1;i<=m;i++)ans=min(ans,f[i]); printf("1\n%d",ans); return 0; }
D2T1——无线网络发射器选址——简单模拟(又是一句话)
倒是我一开始把题目看错了,以为T1巨丧。。
#include<iostream> #include<cstdio> using namespace std; inline int read(){ int t=1,num=0;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();} while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();} return num*t; } int n,d,a[129][129]; inline int max(int x){return x>0?x:0;} inline int min(int x){return x<128?x:128;} int check(int x,int y){ int num=0; int l=max(y-d),r=min(y+d),s=max(x-d),t=min(x+d); for(int i=l;i<=r;i++) for(int j=s;j<=t;j++) num+=a[i][j]; return num; } int main() { d=read();n=read(); for(int i=1;i<=n;i++){ int x=read(),y=read();a[x][y]=read(); } int ans=1,big=0; for(int i=0;i<129;i++){ for(int j=0;j<129;j++){ int num=check(i,j); if(big==num)ans++; if(big<num){ans=1;big=num;} } } printf("%d %d\n",ans,big); return 0; }
D2T2——寻找道路
好像不是很丧
就先用反向边跑一遍,求出T点不能到的点。
然后枚举一下每一个点,
标记上每个“连向T点不能到的点”的点,包括本身(T点不能到的点)。
然后跑一遍最短路就好了。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<vector> #include<queue> using namespace std; inline int read(){ int t=1,num=0;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();} while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();} return num*t; } const int N=10010; vector<int> g[N],f[N]; int n,m,visit[N],no[N],d[N]; void bfs(int t){ queue<int> q; q.push(t);visit[t]=1; while(!q.empty()){ int x=q.front();q.pop(); for(int i=0;i<f[x].size();i++){ int y=f[x][i]; if(!visit[y]){visit[y]=1;q.push(y);} } } for(int i=1;i<=n;i++){ if(!visit[i]){ no[i]=1; for(int j=0;j<f[i].size();j++) no[f[i][j]]=1; } } } void dij(int s){ for(int i=1;i<=n;i++)d[i]=1e9; queue<int>q; q.push(s);d[s]=0; while(!q.empty()){ int x=q.front();q.pop(); for(int i=0;i<g[x].size();i++){ int y=g[x][i]; if(d[x]+1<d[y]&&(!no[y])){ d[y]=d[x]+1; q.push(y); } } } } int main() { n=read();m=read(); for(int i=1;i<=m;i++){ int x=read(),y=read(); g[x].push_back(y); f[y].push_back(x); } int s=read(),t=read();bfs(t);dij(s); printf("%d\n",(d[t]==1e9?-1:d[t])); return 0; }
D2T3——解方程
这题感觉挺好骗分的,代码也很好打。
随随便便暴力就30分。
暴力加个随随便便的高精度就50分。
随随便便将a0+a1*k^1+a2*k^2+...+an*k^n(1<=k<=m)取膜就70分。
然后随随便便加个优化——从1循环到mod的大小就100分。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; inline int read(){ int t=1,num=0;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();} while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();} return num*t; } const int mod[5]={14153,19973,33377,11941,20719}; int n,m,num[110]; char a[110][10010]; bool t[1000010]; int main() { n=read();m=read(); for(int i=0;i<=n;i++)scanf("%s",a[i]); for(int k=0;k<5;k++){ int mo=mod[k]; memset(num,0,sizeof(num)); for(int i=0;i<=n;i++){ int l=strlen(a[i]),f=1; if(a[i][0]=='-')f=-1; else num[i]=a[i][0]-'0'; for(int j=1;j<l;j++) num[i]=(num[i]*10+a[i][j]-'0')%mo; num[i]*=f; } for(int i=1;i<=mo;i++){ int sum=0; for(int j=n;j>=0;j--) sum=(sum*i+num[j])%mo; if(sum!=0){ int j=i;t[j]=1; while(j+mo<=m){ j+=mo;t[j]=1; } } } } int ans=0; for(int i=1;i<=m;i++)if(!t[i])ans++; printf("%d\n",ans); for(int i=1;i<=m;i++) if(!t[i])printf("%d\n",i); return 0; }
本文由Yzyet编写,网址为www.cnblogs.com/Yzyet。非Yzyet同意,禁止转载,侵权者必究。