签到,判断是否360倍数,dfs解决;
#include<bits/stdc++.h> using namespace std; bool flag; int a[100]; int n; void dfs(int pass,int sum){ if((sum%360==0)&&pass==n){flag=1;return ;} if(flag||pass==n)return ; dfs(pass+1,sum+a[pass+1]); dfs(pass+1,sum-a[pass+1]); } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); flag=0; dfs(1,a[1]); if(flag)puts("YES"); else puts("NO"); // system("pause"); return 0; }
B - B
裸的二分图染色,dfs解决,bfs不可;
#include<bits/stdc++.h> using namespace std; #define pb push_back typedef long long ll; const int inf=0x3f3f3f3f; const int N=2e5+5; struct edge{int u,v;edge(int a,int b){u=a,v=b;}}; vector<int>e[N]; vector<edge>t; int color[N]; bool flag; void dfs(int u,int pass){ color[u]=pass; if(!flag)return ; for(int i=0;i<e[u].size();i++){ int v=e[u][i]; if(color[v]<0)dfs(v,1-pass); if(color[v]==color[u]){flag=0;return ;} } } int main(){ int n,m; scanf("%d %d",&n,&m); for(int i=1;i<=n;i++)color[i]=-1; while(m--){ int u,v; scanf("%d %d",&u,&v); e[u].pb(v);e[v].pb(u); t.pb(edge(u,v)); } flag=1; dfs(1,1); if(!flag){puts("NO");return 0;} puts("YES"); string s; for(int i=0;i<t.size();i++){ if(color[t[i].u]==1)s+='1'; else s+='0'; } cout<<s<<endl; // system("pause"); return 0; }
C - C
留坑
题意:看完题解我笑了,不知如何说起;
有如下规律
a[i-1] a[i] a[i+1]
差分: a[i]-a[i-1] a[i+1]-a[i]
变换后:a[i-1] a[i-1]+a[i+1]-a[i] a[i+1]
差分:a[i+1]-a[i] a[i]-a[i-1]
意思就是变换后的差分序列只是变了顺序;
枚举c数组和t数组的差分,然后特判一下;
#include<bits/stdc++.h> using namespace std; #define pb push_back const int N=1e5+5; int c[N],t[N],dc[N],dt[N]; int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&c[i]); for(int i=1;i<=n;i++)scanf("%d",&t[i]); for(int i=2;i<=n;i++)dc[i]=c[i]-c[i-1]; for(int i=2;i<=n;i++)dt[i]=t[i]-t[i-1]; sort(dc+2,dc+1+n); sort(dt+2,dt+1+n); if(c[1]!=t[1]||t[n]!=t[n]){puts("No");return 0;}; for(int i=2;i<=n;i++){ if(dc[i]!=dt[i]){puts("No");return 0;} } puts("Yes"); return 0; }
D - D
两种解法;
解法1:一一枚举;四种情况;
#include<cstdio> #include<vector> #include<queue> #include<algorithm> using namespace std; #define pb push_back typedef long long ll; const int inf=0x3f3f3f3f; const int N=1e5+5; struct point{int x, y;}P[N]; int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d %d",&P[i].x,&P[i].y); int ans=0; for(int i=2;i<n;i++){ if(P[i].y==P[i-1].y&&P[i].x>P[i-1].x&&P[i+1].x==P[i].x&&P[i+1].y>P[i].y)ans++; else if(P[i].x==P[i-1].x&&P[i].y>P[i-1].y&&P[i].y==P[i+1].y&&P[i].x>P[i+1].x)ans++; else if(P[i].y==P[i-1].y&&P[i].x<P[i-1].x&&P[i+1].x==P[i].x&&P[i].y>P[i+1].y)ans++; else if(P[i].x==P[i-1].x&&P[i].y<P[i-1].y&&P[i].y==P[i+1].y&&P[i].x<P[i+1].x)ans++; } printf("%d ",ans); // system("pause"); return 0; }
解法二:观察上面图像,b必在a的逆时针方向,叉积判断即可;
#include<bits/stdc++.h> #define rep(i,j,k) for(int i=(int)j;i<=(int)k;i++) #define per(i,j,k) for(int i=(int)k;i>=(int)j;i++) #define pb push_back using namespace std; typedef long long ll; const int N=1e3+5; const double eps=1e-8; // struct Point{int x,y;}P[N]; struct point{ int x,y; point(){} point(int a,int b):x(a),y(b){} // point(int a,int b){x=a,y=b;} }P[N]; point Vector(point a,point b){return point(b.x-a.x,b.y-a.y);} // int dot(point a,point b){} int main(){ int n; scanf("%d",&n); int ans=0; for(int i=1;i<=n;i++)scanf("%d %d",&P[i].x,&P[i].y); for(int i=2;i<n;i++){ point a=Vector(P[i-1],P[i]); point b=Vector(P[i],P[i+1]); if((a.x*b.y-a.y*b.x)>0)ans++; } cout<<ans<<endl; // system("pause"); return 0; }
E - E
dp,有点类似背包;
每一步可以中速,高速,慢速,
#include<bits/stdc++.h> using namespace std; const int inf=0x3f3f3f3f; const int N=2e2+15; int t1[N],t2[N],t3[N],f1[N],f2[N]; int dp[N][N]; int main(){ int t,n,m; scanf("%d",&t); while(t--){ scanf("%d %d",&n,&m); for(int i=1;i<=n;i++) scanf("%d %d %d %d %d",&t1[i],&t2[i],&t3[i],&f1[i],&f2[i]); memset(dp,inf,sizeof dp); dp[0][m]=0; for(int i=1;i<=n;i++) for(int j=0;j<=m;j++){ if(j>=f1[i]&&dp[i][j-f1[i]]>dp[i-1][j]+t1[i]) dp[i][j-f1[i]]=dp[i-1][j]+t1[i]; if(dp[i][j]>dp[i-1][j]+t2[i]) dp[i][j]=dp[i-1][j]+t2[i]; if(j+f2[i]<=m&&dp[i][j+f2[i]]>dp[i-1][j]+t3[i]) dp[i][j+f2[i]]=dp[i-1][j]+t3[i]; if(j+f2[i]>=m&&dp[i][m]>dp[i-1][j]+t3[i]) dp[i][m]=dp[i-1][j]+t3[i]; } int ans=inf; for(int j=0;j<=m;j++) ans=min(ans,dp[n][j]); printf("%d ",ans); } // system("pause"); return 0; }
题意:求n个数里每次选一个数异或,值最大;
字典树解决;
其实和字符串一样,能优化是因为只有01情况,高位枚举;
#include<bits/stdc++.h> using namespace std; const int inf=0x3f3f3f3f; const int N=1e5+15; typedef long long ll; ll trie[32*N][2]; int val[N*32]; int tot; void insert(ll x){ int u=0; for(int i=32;i>=0;i--){ int id=(x>>i)&1; if(!trie[u][id])trie[u][id]=++tot; u=trie[u][id]; } val[u]=x; } int query(ll x){ int u=0; for(int i=32;i>=0;i--){ int id=(x>>i)&1; if(trie[u][id^1])u=trie[u][id^1]; else u=trie[u][id]; } return val[u]; } int main(){ int t,n,m,cas=0; scanf("%d",&t); while(t--){ memset(trie,0,sizeof trie); // memset(val,0,sizeof val); tot=0; scanf("%d %d",&n,&m); ll x; for(int i=1;i<=n;i++){scanf("%lld",&x);insert(x);}; printf("Case #%d: ",++cas); while(m--){ scanf("%lld",&x); printf("%lld ",query(x)); } } // system("pause"); return 0; }
水
#include<bits/stdc++.h> using namespace std; #define rep(i,j,k) for(int i=(int)j;i<=(int)k;i++) #define per(i,j,k) for(int i=(int)k;i>=(int)j;i--) #define pb push_back #define se second #define fi first const int N=1e4+5; int a[N]; int main(){ int t; scanf("%d",&t); while(t--){ int n; scanf("%d",&n); map<int,int>mp; set<int>st; for(int i=1;i<=4*n;i++)scanf("%d",&a[i]),st.insert(a[i]),mp[a[i]]++; sort(a+1,a+1+4*n); int flag=1; for(int i=1;i<=4*n;i++)if(mp[a[i]]&1){flag=0;break;} if(!flag){puts("NO");continue;} // vector<int> vector<int>v; map<int,int>::iterator it; for(it=mp.begin();it!=mp.end();it++){ for(int i=1;i<=( (it->se)/2 );i++)v.pb( it->fi ); } sort(v.begin(),v.end()); int sz=v.size(); if(sz&1){puts("NO");continue;} int sum=v[0]*v[sz-1]; for(int i=1;i<(sz/2);i++){ if(v[i]*v[sz-i-1]!=sum){flag=0;break;} } if(!flag){puts("NO");continue;} else puts("YES"); } // system("pause"); return 0; }
I - I
签到;
#include<cstdio> using namespace std; const int maxn=1e6+5; int fa[maxn]; int find(int x){ if(x==fa[x])return x; else return fa[x]=find(fa[x]); // return fa[x]==x?x:find(fa[x]); } void build(int x,int y){ int dx=find(x); int dy=find(y); fa[dx]=dy; } int main(){ int t,n,m; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); for(int i=1;i<=2*n;i++)fa[i]=i; char op; int x,y; while(m--){ getchar(); scanf("%c%d%d",&op,&x,&y); if(op=='D'){ build(x,y+n); build(x+n,y); } else { if(find(x)==find(y+n)) printf("In different gangs. "); else if(find(x)==find(y)) printf("In the same gang. "); else printf("Not sure yet. "); } } } return 0; }
留坑