Educational Codeforces Round 2
A. Extract Numbers
【题意】给定一个字符串,把用逗号或分号隔开的子串称为一个word,第一行输出所有由整数组成的word(01,1.0不算整数),第二行输出剩余所有word。不改变word的前后顺序,并用逗号隔开。
【分析】判断word是否为整数时需要注意。
【代码】
#include<cstdio> #include<iostream> #include<cstring> #include<iostream> #include<vector> using namespace std; string s; string a; string b; vector<string> v; int numbers(int m) { int len=v[m].length(); if(len==0) return 0; for(int i=0;i<len;i++) { if(!isdigit(v[m][i])) return 0; if(len>1&&v[m][0]=='0') return 0; } return 1; } int main (void) { cin>>s; a='\"'; b='\"'; s+=';'; int begin=0; for(int i=0;i<=s.length();i++) { if(s[i]==';'||s[i]==',') { v.push_back(s.substr(begin,i-begin)); begin=i+1; } } for(int i=0;i<v.size();i++) { if(numbers(i)) a+=v[i], a+=','; else b+=v[i], b+=','; } a[a.length()-1]='\"'; b[b.length()-1]='\"'; if(a.length()==1 ) cout<<'-'<<endl; else cout<<a<<endl; if(b.length()==1) cout<<'-'<<endl; else cout<<b<<endl; }
B. Queries about less or equal elements
【分析】(正好用上刚会的upper_bound)将数组排好序,获取第一个大于该值的元素的下标,即为小于等于该值的元素个数。
【代码】
#include<cstdio> #include<iostream> #include<cstring> #include<iostream> #include<vector> #include<algorithm> using namespace std; const int maxn=200005; typedef long long ll; int a[maxn]; int b[maxn]; int c[maxn]; int main (void) { int n,m; cin>>n>>m; for(int i=0;i<n;i++) cin>>a[i]; sort(a,a+n); for(int i=0;i<m;i++) { cin>>b[i]; c[i]=upper_bound(a,a+n,b[i])-a; } for(int i=0;i<m;i++) cout<<c[i]<<" "; }
C. Make Palindrome
【题意】更改字符串中的字母,使得重新组合后的字符串是回文串,求最少的变更次数
【分析】贪心,为使最终改变次数最少且字典序最小:首先用数组记录字符串中字母出现次数,并定义两个指针,分别指向a和z,依次逼近。
- 如果一个字母出现次数为偶数,则不改变。
- 如果两个字母出现次数为奇数,则将字典序较大的字母更改成字典序较小的字母。
最后按字典序输出字符串。
【代码】
#include<cstdio> #include<cstring> #include<iostream> #include<vector> #include<algorithm> #include<cmath> using namespace std; string s; const int maxn=200005; int cnt[maxn]; int main (void) { cin>>s; for(int i=0;i<s.length();i++) cnt[s[i]]++; int begin='a'; int end='z'; int len=s.length(); while(begin<end) { while(begin<end&&cnt[begin]%2==0) begin++; cnt[begin]++; while(begin<end&&cnt[end]%2==0) end--; cnt[end]--; } int j=0; for(int i='a';i<='z';i++) { while(cnt[i]>=2) { s[j]=s[len-j-1]=i; cnt[i]-=2; j++; } if(cnt[i]==1) s[len/2]=i; } cout<<s<<endl; }
D. Area of Two Circles' Intersection
【题意】给定两个圆的圆心坐标和半径,求两个圆相交的面积
【分析】新get的两个圆相交面积模板
【代码】
#include<cstdio> #include<cstring> #include<iostream> #include<vector> #include<algorithm> #include<cmath> #include<iomanip> using namespace std; const long double PI=acos(-1.0); struct Round { long double x,y; long double r; long double K(long double x) { return x*x; } long double Dis(Round a,Round b) { return sqrt(K(a.x-b.x)+K(a.y-b.y)); } long double Intersection_area(Round a,Round b) { long double dis=Dis(a,b); if(a.r==0||b.r==0||dis>=a.r+b.r)return 0; else if(dis<=fabs(a.r-b.r))return PI*K(min(a.r,b.r)); else { long double angA=2*acos( (K(a.r)+K(dis)-K(b.r))/(2*a.r*dis) ); long double angB=2*acos( (K(b.r)+K(dis)-K(a.r))/(2*b.r*dis) ); long double areaA=K(a.r)*(angA-sin(angA))/2; long double areaB=K(b.r)*(angB-sin(angB))/2; return areaA+areaB; } } }a,b; int main() { cin>>a.x>>a.y>>a.r>>b.x>>b.y>>b.r; cout<<setprecision(25)<<a.Intersection_area(a,b)<<endl; return 0; }
C题想了好久都不会,后来看了题解才懂。笨死啦~~~