AtCoder Beginner Contest 157(题解)
A - Duplex Printing
思路:判断一下奇偶就好了
#include<iostream> #include<algorithm> #include<cstring> using namespace std; int main() { int n; cin>>n; int ans=n/2; if(n%2!=0) ans++; cout<<ans<<endl; return 0; }
B - Bingo
思路:按照题意模拟一下即可
#include<iostream> #include<algorithm> using namespace std; int a[4][4],flag[4][4]; int main() { for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) cin>>a[i][j]; int n,ans=0,x; cin>>n; while(n--){ cin>>x; for(int i=1;i<=3;i++){ for(int j=1;j<=3;j++) if(a[i][j]==x) flag[i][j]=1; } } for(int i=1;i<=3;i++){ int cnt=0; for(int j=1;j<=3;j++) if(flag[i][j]) cnt++; if(cnt==3){ cout<<"Yes"<<endl; return 0; } } for(int i=1;i<=3;i++){ int cnt=0; for(int j=1;j<=3;j++) if(flag[j][i]) cnt++; if(cnt==3){ cout<<"Yes"<<endl; return 0; } } if(flag[1][1]+flag[2][2]+flag[3][3]==3||flag[1][3]+flag[2][2]+flag[3][1]==3){ cout<<"Yes"<<endl; return 0; } cout<<"No"<<endl; return 0; }
C - Guess The Number
思路:开一个数组存每个位置上的数即可,如果矛盾了或者出现前置0就不行,要注意一些特殊情况
#include<iostream> #include<algorithm> using namespace std; int a[4]; int main() { int n,m,x,y,flag=0; cin>>n>>m; a[1]=a[2]=a[3]=-1; for(int i=1;i<=m;i++){ cin>>x>>y; if(a[x]!=-1&&a[x]!=y){ flag=1; break; } a[x]=y; } if(flag==1){ cout<<-1<<endl; return 0; } if(a[1]==0&&n!=1){ cout<<-1<<endl; return 0; } if(n==1&&a[1]==-1){ cout<<0<<endl; return 0; } for(int i=1;i<=n;i++){ if(a[i]==-1&&i==1){ cout<<"1"; continue; } if(a[i]==-1) cout<<"0"; else cout<<a[i]; } }
D - Friend Suggestions(并查集)
思路:由于关系具有传递性,所以我们用并查集来存储与查询关系,对个每个人的答案,就为其所在连通块大小减去,他的直接好友再减去一个连通块内有封锁关系的朋友
#include<iostream> #include<algorithm> #include<vector> using namespace std; const int maxn=1e5+10; typedef long long ll; int fa[maxn],siz[maxn]; vector<int> a[maxn],b[maxn]; int find(int x){return (x==fa[x])?x:fa[x]=find(fa[x]);} int main() { int n,m,k,u,v; scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++){ fa[i]=i; siz[i]=1; } for(int i=1;i<=m;i++){ scanf("%d%d",&u,&v); int f1=find(u),f2=find(v); if(f1!=f2){ siz[f1]+=siz[f2]; fa[f2]=f1; } a[u].push_back(v); a[v].push_back(u); } for(int i=1;i<=k;i++){ scanf("%d%d",&u,&v); b[u].push_back(v); b[v].push_back(u); } for(int i=1;i<=n;i++){ int ans=siz[find(i)]-1; ans-=a[i].size(); for(int j=0;j<b[i].size();j++){ if(find(i)==find(b[i][j])) ans--; } cout<<ans<<" "; } return 0; }
E - Simple String Queries(线段树/STL)
思路:
方法一:建立26棵线段树
方法二:建立26个set,每个set存相应字母出现的位置
对于修改,先在原来的字母对应的set中删除位置,再在更新的字母对应的set中插入位置
由于set中元素都为有序的,所以每次询问,在每个set中进行二分找l如果找到的元素小于等于r答案就加一
#include<iostream> #include<algorithm> #include<set> using namespace std; set<int> a[26]; string temp; int main() { cin>>temp; int n,op,pos,l,r; char ch; for(int i=0;i<temp.size();i++) a[temp[i]-'a'].insert(i+1); scanf("%d",&n); while(n--){ scanf("%d",&op); if(op==1){ cin>>pos>>ch; a[temp[pos-1]-'a'].erase(pos); temp[pos-1]=ch; a[temp[pos-1]-'a'].insert(pos); } else{ cin>>l>>r; int num=0; for(int i=0;i<26;i++){ set<int>::iterator it; it=a[i].lower_bound(l); if(it!=a[i].end()&&*it<=r) num++; } cout<<num<<endl; } } return 0; }