Codeforces Round #603 (Div. 2)
Codeforces Round #603 (Div. 2)
题意:多组数据,每组数据给出3种颜色的糖果,规定每天吃2颗糖果,颜色不能相同,问最多吃几天。
思路:3种糖果按照个数多少排序得到a≤b≤c,①若a+b≤c,则每天吃 c 和 a,b中的一种,可以吃a+b天。②若a+b>c,则先吃a和c让c和b一样多,然后若剩余的a为偶数则所有糖可以都吃完,若为奇数则最后会剩余1颗,所以此种情况对应天数为(a+b+c)/2天。
#include<bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); long long n; long long num[3]; cin>>n; while(n--){ cin>>num[0]>>num[1]>>num[2]; sort(num,num+3); if(num[0]+num[1]<=num[2]){ cout<<num[0]+num[1]<<endl; }else{ cout<<(num[0]+num[1]+num[2])/2<<endl; } } return 0; }
题意:多组数据,每组数据给出n个4位密码,现在要让给出的密码两两不相同,且每次只能更改一个密码的1位,问至少修改多少次并按顺序输出更改后的所有密码。
思路:因为n最大为10,所以密码修改可以只考虑1位,可以先把所有的pin code都放入一个unordered_map中并统计相应的个数,然后将重复的pin code最后一位进行更改找到没出现过的即可。
#include<bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); int t; cin>>t; string shuru[20]; while(t--){ int n,ans=0; unordered_map<string,int>tree; cin>>n; for(int i=1;i<=n;i++){ cin>>shuru[i]; if(tree.find(shuru[i])==tree.end()){ tree[shuru[i]]=1; }else{ tree[shuru[i]]++; } } for(auto i=tree.begin();i!=tree.end();i++){ ans+=(*i).second-1; } cout<<ans<<endl; for(int i=1;i<=n;i++){ if(tree[shuru[i]]>1){ string s=shuru[i]; for(int j=0;j<=9;j++){ s[3]=j+'0'; if(tree.find(s)==tree.end()){ tree[s]=1; cout<<s<<endl; tree[shuru[i]]--; break; } } }else{ cout<<shuru[i]<<endl; } } } return 0; }
题意:多组数据,每组数据给出一个分值n,定义每个人的得分为n除以人数k(向下取整),问一共有多少种不同的分数。
思路:对于给定的n,i 从1循环到√n,(n/i) 和 (n/(n/i)) 是不同的分数,最后把0加上即可。
#include<bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); int t; cin>>t; while(t--){ long long n; set<long long>tree; cin>>n; for(long long i=1;i*i<=n;i++){ long long ans=n/i; if(tree.find(ans)==tree.end()){ tree.insert(ans); tree.insert(n/ans); } } tree.insert(0); cout<<tree.size()<<endl; for(auto i=tree.begin();i!=tree.end();i++){ cout<<(*i)<<" "; } cout<<endl; } return 0; }
题意:有n个密码,每个密码都是由小写字母则称,现在给密码分类,有2个标准。
· 若 密码a 和 密码b 都含有某个相同的字母,则a和b同类
· 若 密码a 和 密码c 同类,密码b 和 密码c 同类,则 密码a 和 密码b 同类。
问有几种不同类型的密码。
思路:并查集,依次将所有含有字母a的密码视为一个集团,merge在一起。再将含有字母b的密码视为一个集团,merge在一起……以此类推到字母z。最后查询有几个不同的集团即可。
#include<bits/stdc++.h> using namespace std; int father[200005]; vector<vector<int> >vec(27); void init(int n){ for(int i=1;i<=n;i++){ father[i]=i; } return; } int getfather(int x){ if(father[x]==x) return x; else return father[x]=getfather(father[x]); } void merge(int x,int y){ int xx=getfather(x); int yy=getfather(y); if(xx<yy){ father[xx]=yy; }else{ father[yy]=xx; } } int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); int n; string s; cin>>n; init(n); for(int i=1;i<=n;i++){ cin>>s; unordered_set<char>tree; for(int j=0;j<s.size();j++){ tree.insert(s[j]); } for(auto j=tree.begin();j!=tree.end();j++){ vec[(*j)-'a'].push_back(i); } } for(int i=0;i<26;i++){ for(int j=1;j<vec[i].size();j++){ merge(vec[i][j-1],vec[i][j]); } } unordered_set<int>ans; for(int i=1;i<=n;i++){ ans.insert(getfather(father[i])); } cout<<ans.size()<<endl; return 0; }
题意:你要对文本进行编辑,你一开始的下标为起始点(文本范围是左边从起始点开始到右边可以为无穷远),你有n个操作,‘R’和‘L’分别是向右移动1格光标和向左移动一格光标(向左不能越过起始点),其他字符X为替换该光标对应位置的文本为X,每次操作后进行一个查询,查询全部文本的括号是否合法,若不合法输出-1,若合法则输出全部括号的最大深度。
思路:强制在线操作。对于所有的操作可以分为3类,添加括号,删除括号和无影响。(将起始点坐标视为1)在 i 位置添加一个 “(” ,则视为对区间 [ 1 , i ]所有数减一。i 位置添加一个“)”,则视为对区间[ 1 , i ]所有数加一。删除括号则相反。每次查询若左端点若为0且全部区间[1,n]的最小值大于0,则括号合法,且全部区间[1,n]的最大值为括号的最大深度。可以维护一颗线段树进行区间更新和维护区间最值。
#include <iostream> #include <cstdio> #define ll long long using namespace std; const ll MAXN = 1e6+10; struct Tree { ll l,r;//节点左右端点 ll sum;//求和 ll lazy;//延迟标记 ll maxn;//最大值 ll minn;// 最小值 } tree[MAXN<<2]; char zifu[1000005]; void push_up(ll node) { tree[node].sum=tree[node<<1].sum+tree[node<<1|1].sum; tree[node].maxn=max(tree[node<<1].maxn,tree[node<<1|1].maxn); tree[node].minn=min(tree[node<<1].minn,tree[node<<1|1].minn); } void push_down(ll node, ll length) { if(tree[node].lazy) { tree[node<<1].lazy+=tree[node].lazy; tree[node<<1|1].lazy+=tree[node].lazy; tree[node<<1].sum+=(length-(length>>1))*tree[node].lazy; tree[node<<1|1].sum+=(length>>1)*tree[node].lazy; tree[node<<1].minn+=tree[node].lazy; tree[node<<1|1].minn+=tree[node].lazy; tree[node<<1].maxn+=tree[node].lazy; tree[node<<1|1].maxn+=tree[node].lazy; tree[node].lazy = 0; } } void build(ll l,ll r, ll node) { tree[node].lazy = 0; tree[node].l=l; tree[node].r=r; if(l==r) { //cin>>tree[node].sum; tree[node].sum=0; tree[node].minn=tree[node].sum; tree[node].maxn=tree[node].sum; return; } ll mid=(l+r)>>1; build(l,mid,node<<1); build(mid+1,r,node<<1|1); push_up(node); } void update(ll left,ll right,ll key, ll node) { if(tree[node].l>=left && tree[node].r<=right) { tree[node].sum+=(tree[node].r-tree[node].l+1)*key; tree[node].minn+=key; tree[node].maxn+=key; tree[node].lazy+=key; return; } push_down(node,tree[node].r-tree[node].l+1); ll mid=(tree[node].r+tree[node].l)>>1; if(left<=mid) update(left,right,key,node<<1); if(right>mid) update(left,right,key,node<<1|1); push_up(node); } ll query(ll left,ll right,ll node) { if(tree[node].l>=left && tree[node].r<=right) { return tree[node].sum; } push_down(node,tree[node].r-tree[node].l+1); ll mid=(tree[node].r+tree[node].l)>>1; ll ans=0; if(left<=mid) ans+=query(left,right,node<<1); if(right>mid) ans+=query(left,right,node<<1|1); return ans; } ll query_min(ll left,ll right,ll node) { if(tree[node].l>=left && tree[node].r<=right) { return tree[node].minn; } push_down(node,tree[node].r-tree[node].l+1); ll mid=(tree[node].r+tree[node].l)>>1; ll ans=0x7fffffff; if(left<=mid) ans=min(ans,query_min(left,right,node<<1)); if(right>mid) ans=min(ans,query_min(left,right,node<<1|1)) ; return ans; } ll query_max(ll left,ll right,ll node) { if(tree[node].l>=left && tree[node].r<=right) { return tree[node].maxn; } push_down(node,tree[node].r-tree[node].l+1); ll mid=(tree[node].r+tree[node].l)>>1; ll ans=-0x7fffffff; if(left<=mid) ans=max(ans,query_max(left,right,node<<1)); if(right>mid) ans=max(ans,query_max(left,right,node<<1|1)); return ans; } int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); int n,point=1,last_ans=0; cin>>n; build(1,n,1); string s; cin>>s; for(int i=0;i<s.size();i++){ if(s[i]=='R'){ cout<<last_ans<<" "; point++; }else if(s[i]=='L'){ cout<<last_ans<<" "; point=max(1,point-1); }else{ if(zifu[point]=='('){ update(1,point,1,1); }else if(zifu[point]==')'){ update(1,point,-1,1); } if(s[i]=='('){ update(1,point,-1,1); }else if(s[i]==')'){ update(1,point,1,1); } int minn=query_min(1,n,1); int maxx=query_max(1,n,1); int left_point=query(1,1,1); if(minn<0 || left_point!=0){ cout<<-1<<" "; last_ans=-1; }else{ cout<<maxx<<" "; last_ans=maxx; } zifu[point]=s[i]; } } cout<<endl; return 0; }