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

【题意】给定数组a,b。对于数组b中每个元素,求出数组a中小于等于该元素的元素个数。

【分析】(正好用上刚会的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题想了好久都不会,后来看了题解才懂。笨死啦~~~


原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758865.html