标签:
A. Cards
题解:
目的是将n个数分成n/2个人,每个人2个,要求和一样,保证有解
排序一下再选取就行了
代码:
#include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define ll long long typedef pair<int,int> P; const int INF=1e9+10; const int maxn=110; ll read() { ll x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } //----------------------------------------------------------------------------- P a[110]; int main() { int n; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i].fs; a[i].se=i; } sort(a+1,a+n+1); for(int i=1;i<=n/2;i++) cout<<a[i].se<<" "<<a[n+1-i].se<<endl; }
B. Cells Not Under Attack
题解:
给出一个n*n的格子,然后m个点,每个点的横纵坐标的位置不可选,问每次放置一个点,剩余多少点可选取
模拟,自己手动画一画就知道了
代码:
#include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define ll long long typedef pair<int,int> P; const int INF=1e9+10; const int maxn=100100; ll read() { ll x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } //----------------------------------------------------------------------------- int x[maxn],y[maxn]; int main() { ll n,m; int a,b; cin>>n>>m; ll sum=n*n; int cnt_x=0,cnt_y=0; for(int i=1;i<=m;i++) { cin>>a>>b; if(x[a]==0&&y[b]==0) { sum-=(n+n-1-cnt_x-cnt_y); cnt_x++; cnt_y++; x[a]=1; y[b]=1; } else if(x[a]==1&&y[b]==0) { sum-=(n-cnt_x); y[b]=1; cnt_y++; } else if(y[b]==1&&x[a]==0) { sum-=(n-cnt_y); x[a]=1; cnt_x++; } cout<<sum<<" "; } cout<<endl; return 0; }
C. They Are Everywhere
题解:
给你一段字符串,求包含所有字符串的最短长度
滑动窗口一下即可,维护所有字符串
代码:
#include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define ll long long typedef pair<int,int> P; const int INF=1e9+10; const int maxn=100100; ll read() { ll x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } //----------------------------------------------------------------------------- int n; string s; set<char> m; int low[30],upp[30]; int Check() { int cnt=0; for(int i=0;i<30;i++) { if(low[i]>0) cnt++; if(upp[i]>0) cnt++; } return cnt; } int main() { cin>>n; string s; cin>>s; int len=s.length(); for(int i=0;i<len;i++) m.insert(s[i]); int gol=m.size(),st=0,cnt=INF; if(islower(s[0])) low[s[0]-‘a‘]++; if(isupper(s[0])) upp[s[0]-‘A‘]++; if(Check()==gol) cout<<1<<endl; else { for(int i=1;i<n;i++) { if(islower(s[i])) low[s[i]-‘a‘]++; if(isupper(s[i])) upp[s[i]-‘A‘]++; while(Check()==gol) { cnt=min(cnt,i-st+1); if(islower(s[st])) low[s[st]-‘a‘]--; if(isupper(s[st])) upp[s[st]-‘A‘]--; st++; } } cout<<cnt<<endl; } }
D. As Fast As Possible
题解:
有n个人,要到路程为l的地方去,人的速度为v1,车的速度为v2,车的容量为k,求最短时间
YY一下不难发现,最后当所有人同时到达目的地时间最短,那么,最后车和人同时到达,也就是每个人行走和用车的时间是相同的
车子所走路程分两段,第一个段是直走的路程,第二段是返回的路程。不难发现,返回的路程和等于x=l-t*v1。直走路程所用时间x/(v2-v1),返回时间x/(v2+v1)。直走了(n-1)/k+1次。返回走了(n-1)/k+1-1次
然后二分出来
代码:
#include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define ll long long #define CLR(x) memset(x,0,sizeof x) #define SZ(x) ((int)(x).size()) #define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++) typedef pair<int,int> P; const double eps=1e-15; const int maxn=100010; ll read() { ll x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } //----------------------------------------------------------------------------- int n,l,v1,v2,k,T; bool Check(double tim) { double len=l-tim*v1; return T*(len/(v2-v1))+(T-1)*(len/(v2+v1))>tim; } int main() { cin>>n>>l>>v1>>v2>>k; T=(n-1)/k+1; double le=(double)l/v2,ri=(double)l/v1,mid; for(int i=0;i<100;i++) { mid=(le+ri)/2; if(Check(mid)) le=mid; else ri=mid; } cout<<setprecision(9)<<(le+ri)/2<<endl; }
E. Connecting Universities
题解:
给出一个节点为n的树,已经2k个节点。要求这2k个节点所组成的k对节点的距离和的最大值
记录每条边对总和的贡献的最大值即可.最大值为min(p[u],p[t]),p[u],p[t]表示以u--t边为边界两侧的大学的数量,通过dfs求得一侧的数量,另一侧直接2*m-p[u]即可
代码:
#include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define ll long long #define CLR(x) memset(x,0,sizeof x) #define SZ(x) ((int)(x).size()) #define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++) typedef pair<int,int> P; const double eps=1e-15; const int maxn=200100; ll read() { ll x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } //----------------------------------------------------------------------------- int p[maxn],vis[maxn],n,m,a,b; vector<int> G[maxn]; ll ans; void dfs(int s) { vis[s]=1; for(int i=0;i<G[s].size();i++) { if(vis[G[s][i]]) continue; dfs(G[s][i]); ans+=min(p[G[s][i]],m*2-p[G[s][i]]); p[s]+=p[G[s][i]]; } } int main() { ans=0; cin>>n>>m; for(int i=0;i<2*m;i++) { cin>>a; p[a]=1; } for(int i=0;i<n-1;i++) { cin>>a>>b; G[a].pb(b); G[b].pb(a); } dfs(1); cout<<ans<<endl; }
Codeforces Round #364 (Div. 2) ABCDE
标签:
原文地址:http://www.cnblogs.com/byene/p/5715110.html