• 2016-2017 CT S03E06: Codeforces Trainings Season 3 Episode 6(8/13)


    2016-2017 CT S03E06: Codeforces Trainings Season 3 Episode 6

    比赛连接:

    http://codeforces.com/gym/101124/

    代码地址

    http://git.oschina.net/qscqesze/Acm/tree/master/contest/2016-2017 CT S03E06 Codeforces Trainings Season 3 Episode 6?dir=1&filepath=contest%2F2016-2017+CT+S03E06+Codeforces+Trainings+Season+3+Episode+6&oid=25d818184806af64cbeb5a0e6235eeb6f1252004&sha=bdab61c2245418e3be90bd32b6dccc4df0995d8f

    Problem A. The Baguette Master

    题意

    给你一个四边形,让你给这个四边形加上一个长度为2的框,问你这个框的最大的周长是多少。

    题解

    框最多就往上移动或者往下移动,那么2^4枚举一下,然后取一个最大值就好了。

    不过我队友好像不是这样写的。。。

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const double pi=acos(-1);
    const double eps=1e-9;
    
    int main()
    {
        double tha,thb,thc,thd,w,ab,bc,cd,da,ac,ans,AB,BC,CD,DA,AC,BD;
        scanf("%lf%lf%lf%lf%lf%lf",&w,&ab,&bc,&cd,&da,&ac);
        thb=acos((ab*ab+bc*bc-ac*ac)/(2.0*ab*bc));
        thd=acos((cd*cd+da*da-ac*ac)/(2.0*cd*da));
        tha=acos((ab*ab+ac*ac-bc*bc)/(2.0*ab*ac))+acos((da*da+ac*ac-cd*cd)/(2.0*da*ac));
        thc=acos((bc*bc+ac*ac-ab*ab)/(2.0*bc*ac))+acos((cd*cd+ac*ac-da*da)/(2.0*cd*ac));
        if(fabs(tha-pi)<eps)
        {
            BC=bc+(w*cos(thb)/sin(thb)+w*cos(thc)/sin(thc));
            CD=cd+(w*cos(thc)/sin(thc)+w*cos(thd)/sin(thd));
            BD=ab+da+(w*cos(thd)/sin(thd)+w*cos(thb)/sin(thb));
            ans=CD+BD+BC+2.0*(w/sin(thb)+w/sin(thc)+w/sin(thd));
        }
        else if(fabs(thb-pi)<eps)
        {
            CD=cd+(w*cos(thc)/sin(thc)+w*cos(thd)/sin(thd));
            DA=da+(w*cos(thd)/sin(thd)+w*cos(tha)/sin(tha));
            AC=ab+bc+(w*cos(tha)/sin(tha)+w*cos(thc)/sin(thc));
            ans=CD+DA+AC+2.0*(w/sin(tha)+w/sin(thc)+w/sin(thd));
        }
        else if(fabs(thc-pi)<eps)
        {
            AB=ab+(w*cos(tha)/sin(tha)+w*cos(thb)/sin(thb));
            DA=da+(w*cos(thd)/sin(thd)+w*cos(tha)/sin(tha));
            BD=bc+cd+(w*cos(thb)/sin(thb)+w*cos(thd)/sin(thd));
            ans=AB+BD+DA+2.0*(w/sin(tha)+w/sin(thb)+w/sin(thd));
        }
        else if(fabs(thd-pi)<eps)
        {
            AB=ab+(w*cos(tha)/sin(tha)+w*cos(thb)/sin(thb));
            BC=bc+(w*cos(thb)/sin(thb)+w*cos(thc)/sin(thc));
            AC=cd+da+(w*cos(thc)/sin(thc)+w*cos(tha)/sin(tha));
            ans=AB+BC+AC+2.0*(w/sin(tha)+w/sin(thb)+w/sin(thc));
        }
        else
        {
            AB=ab+(w*cos(tha)/sin(tha)+w*cos(thb)/sin(thb));
            BC=bc+(w*cos(thb)/sin(thb)+w*cos(thc)/sin(thc));
            CD=cd+(w*cos(thc)/sin(thc)+w*cos(thd)/sin(thd));
            DA=da+(w*cos(thd)/sin(thd)+w*cos(tha)/sin(tha));
            ans=AB+BC+CD+DA+2.0*(w/sin(tha)+w/sin(thb)+w/sin(thc)+w/sin(thd));
        }
      //  cout<<tha<<" "<<thb<<" "<<thc<<" "<<thd<<endl;
      //  cout<<tha+thb+thc+thd<<endl;
        printf("%.12f
    ",ans);
        return 0;
    }
    

    Problem C. Old Chess Sets

    题意

    给你两个集合,问你这两个集合加起来,能不能构成国际象棋的32个棋子。

    题解

    签到题

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    int k1,k2;
    int mp[2][35];
    int num[35];
    int getid(string s){
        if(s=="black")return 0;
        if(s=="white")return 1;
        if(s=="king")return 0;
        if(s=="queen")return 1;
        if(s=="bishop")return 2;
        if(s=="knight")return 3;
        if(s=="rook")return 4;
        if(s=="pawn")return 5;
    }
    vector<string>ans1,ans2;
    int main()
    {
        num[0]=1,num[1]=1,num[2]=2,num[3]=2,num[4]=2,num[5]=8;
        memset(mp,0,sizeof(mp));
        scanf("%d%d",&k1,&k2);
        for(int i=0;i<k1;i++){
            string s1,s2;
            cin>>s1>>s2;
            mp[getid(s1)][getid(s2)]++;
        }
        int flag = 0;
        for(int i=0;i<k2;i++){
            string s1,s2;
            cin>>s1>>s2;
            if(mp[getid(s1)][getid(s2)]<num[getid(s2)])
            {
                mp[getid(s1)][getid(s2)]++;
                ans1.push_back(s1);
                ans2.push_back(s2);
            }
        }
        if(ans1.size()+k1==32){
            for(int i=0;i<ans1.size();i++)
                cout<<ans1[i]<<" "<<ans2[i]<<endl;
        }
        else{
            cout<<"impossible"<<endl;
        }
    }
    

    Problem D. Checkmate with Bishop and Knight

    题意

    给你一个国际象棋的局势,问你应该下哪一步,才能将死对面。

    题解

    直接暴力枚举就好了

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    pair<int,int> pos(string s){
        return make_pair(s[0]-'a',s[1]-'1');
    }
    pair<int,int> bishop,knight,wking,bking;
    int mp[10][10];
    int dkx[8]={1,-1,1,-1,1,-1,0,0},dky[8]={1,-1,-1,1,0,0,1,-1};
    int dbx[4]={1,-1,1,-1},dby[4]={1,-1,-1,1};
    int dnx[8]={1,-1,1,-1,2,-2,2,-2},dny[8]={2,-2,-2,2,1,-1,-1,1};
    bool test(int x,int y)
    {
        for(int i=0;i<8;i++){
            int nx=x+dkx[i];
            int ny=y+dky[i];
            if(nx<0||nx>=8)continue;
            if(ny<0||ny>=8)continue;
            if(mp[nx][ny]==1)return true;
        }
        for(int i=0;i<4;i++){
            for(int j=0;j<8;j++){
                int nx=x+dbx[i]*(j+1);
                int ny=y+dby[i]*(j+1);
                if(nx<0||nx>=8)continue;
                if(ny<0||ny>=8)continue;
                if(mp[nx][ny]==2)return true;
                if(mp[nx][ny])break;
            }
        }
        for(int i=0;i<8;i++){
            int nx=x+dnx[i];
            int ny=y+dny[i];
            if(nx<0||nx>=8)continue;
            if(ny<0||ny>=8)continue;
            if(mp[nx][ny]==3)return true;
        }
        return false;
    }
    bool check()
    {
        if(!test(bking.first,bking.second))
            return 0;
        for(int i=0;i<8;i++){
            int nx=bking.first+dkx[i];
            int ny=bking.second+dky[i];
            if(nx<0||nx>=8)continue;
            if(ny<0||ny>=8)continue;
            if(!test(nx,ny))
                return 0;
        }
        return 1;
    }
    int main()
    {
        string s;
        cin>>s;wking=pos(s),mp[wking.first][wking.second]=1;
        cin>>s;bishop=pos(s),mp[bishop.first][bishop.second]=2;
        cin>>s;knight=pos(s),mp[knight.first][knight.second]=3;
        cin>>s;bking=pos(s),mp[bking.first][bking.second]=4;
        for(int i=0;i<8;i++){
            int nx=knight.first+dnx[i];
            int ny=knight.second+dny[i];
            if(nx<0||nx>=8)continue;
            if(ny<0||ny>=8)continue;
            if(mp[nx][ny])continue;
            mp[nx][ny]=3;
            mp[knight.first][knight.second]=0;
            knight=make_pair(nx,ny);
            if(check()){
                printf("N%c%c
    ",'a'+nx,'1'+ny);
                return 0;
            }
            mp[nx][ny]=0;
            knight=make_pair(nx-dnx[i],ny-dny[i]);
            mp[knight.first][knight.second]=3;
        }
        for(int i=0;i<8;i++){
            int nx=wking.first+dkx[i];
            int ny=wking.second+dky[i];
            if(nx<0||nx>=8)continue;
            if(ny<0||ny>=8)continue;
            if(mp[nx][ny])continue;
            int ff=0;
            for(int j=0;j<8;j++){
                int nnx=nx+dkx[j];
                int nny=ny+dky[j];
                if(nnx<0||nnx>=8)continue;
                if(nny<0||nny>=8)continue;
                if(mp[nnx][nny]==4)ff=1;
            }
            if(ff)continue;
            mp[nx][ny]=1;
            mp[wking.first][wking.second]=0;
            wking=make_pair(nx,ny);
            if(check()){
                printf("K%c%c
    ",'a'+nx,'1'+ny);
                return 0;
            }
            mp[nx][ny]=0;
            wking=make_pair(nx-dkx[i],ny-dky[i]);
            mp[wking.first][wking.second]=1;
    
        }
    
        for(int i=0;i<4;i++){
            for(int j=0;j<8;j++){
                int nx=bishop.first+dbx[i]*(j+1);
                int ny=bishop.second+dby[i]*(j+1);
                if(nx<0||nx>=8)continue;
                if(ny<0||ny>=8)continue;
                if(mp[nx][ny])break;
                mp[nx][ny]=2;
                mp[bishop.first][bishop.second]=0;
                bishop=make_pair(nx,ny);
                if(check()){
                    printf("B%c%c
    ",'a'+nx,'1'+ny);
                    return 0;
                }
                mp[nx][ny]=0;
                bishop=make_pair(nx-dbx[i]*(j+1),ny-dby[i]*(j+1));
                mp[bishop.first][bishop.second]=2;
    
            }
        }
        cout<<"impossible"<<endl;
    }
    

    Problem H. Kids’ Play

    题意

    给你一个有向图图,n点n边,点的度数小于等于2,每个点都在环上

    然后Q次查询,每次查询从一个点开始,问这个点跑k步之后在哪个点上。

    题解

    处理出每个环,然后对于每一个点都倍增处理这个点走2^k步之后在哪儿。

    然后暴力去搞一搞就好了

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+7;
    vector<int> E[maxn],cir[maxn];
    int vis[maxn],p[maxn][2],n,m,cnt,step[maxn][20],be[maxn],two[maxn];
    void dfs(int x)
    {
        if(vis[x])return;
        vis[x]=1;
        cir[cnt].push_back(x);
        be[x]=cnt;
        for(int i=0;i<E[x].size();i++){
            step[x][0]=E[x][i];
            dfs(E[x][i]);
        }
    }
    int main()
    {
        two[0]=1;
        for(int i=1;i<20;i++)
            two[i]=two[i-1]*2;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            p[a][0]=i,p[b][1]=i;
            step[i][0]=i;
        }
        for(int i=1;i<=n;i++)
            E[p[i][1]].push_back(p[i][0]);
        for(int i=1;i<=n;i++)
            if(!vis[i])
            {
                cnt++;
                dfs(i);
            }
        for(int j=1;j<20;j++)
            for(int i=1;i<=n;i++)
                step[i][j]=step[step[i][j-1]][j-1];
        for(int i=1;i<=m;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            b%=cir[be[a]].size();
            int now = a;
            for(int j=19;j>=0;j--)
            {
                if(b>=two[j])
                {
                    now=step[now][j];
                    b-=two[j];
                }
            }
            cout<<now<<endl;
        }
    }
    

    Problem I. Odd Factor (64 MB ML!)

    题意

    给你一个无向图,让你删除一些边,使得每个点的度数都是奇数

    题解

    先找一棵树出来,然后自下而上,如果这个点度数为偶数,就删除这个点与根相连的边就好了

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e6+7;
    vector<int> E[maxn];
    vector<int> id[maxn];
    vector<int>ans1,ans2,ans3;
    int vis[maxn];
    int V[maxn],d[maxn],fa[maxn],p[maxn];
    int n,m,flag=0;
    void dfs(int x)
    {
        vis[x]=1;
        for(int i=0;i<E[x].size();i++){
            if(vis[E[x][i]])continue;
            d[E[x][i]]++;
            d[x]++;
            ans1.push_back(x);
            ans2.push_back(E[x][i]);
            ans3.push_back(1);
            p[E[x][i]]=ans1.size()-1;
            dfs(E[x][i]);
        }
        if(p[x]==-1){
            if(d[x]%2==0)flag=1;
        }else{
            if(d[x]%2==0){
                d[x]--;
                d[ans1[p[x]]]--;
                ans3[p[x]]=0;
            }
        }
    }
    int main()
    {
        memset(p,-1,sizeof(p));
        scanf("%d%d",&n,&m);
        for(int i=0;i<m;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            E[a].push_back(b);
            E[b].push_back(a);
            id[a].push_back(i);
            id[b].push_back(i);
        }
        for(int i=1;i<=n;i++)
            if(!vis[i])dfs(i);
        if(flag){
            cout<<"-1"<<endl;
            return 0;
        }
        int tmp = 0;
        for(int i=0;i<ans1.size();i++)
            if(ans3[i])tmp++;
        cout<<tmp<<endl;
        for(int i=0;i<ans1.size();i++)
            if(ans3[i]==1)
                cout<<ans1[i]<<" "<<ans2[i]<<endl;
        return 0;
    }
    

    Problem K. Average Speed

    题意

    给你每个时间段汽车的速度,多次查询汽车在某个时间一共跑了多远

    题解

    签到题,水题

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    string s;
    double gettime(string s)
    {
        double h = (s[0]-'0')*10+s[1]-'0';
        double m = (s[3]-'0')*10+s[4]-'0';
        double ss = (s[6]-'0')*10+s[7]-'0';
        return h+m/60.0+ss/3600.0;
    }
    int main()
    {
        double now = 0;
        double lasttime = 0;
        double lastspeed = 0;
        while(getline(cin,s))
        {
            if(s.size()>8){
                double time = gettime(s);
                now+=(time-lasttime)*lastspeed;
                lastspeed=0;
                for(int i=9;i<s.size();i++)
                    lastspeed=lastspeed*10+s[i]-'0';
                lasttime=time;
            }
            else{
                double time = gettime(s);
                cout<<s<<" ";
                printf("%.2f km
    ",(time-lasttime)*lastspeed+now);
            }
        }
    }
    

    Problem L. Subway

    题意

    给你一个二维平面,上面有地铁,地铁的速度和人的速度给你

    现在让你从起点到家,问你怎么走最快。

    题解

    把直接走路和地铁的边都扔进邻接矩阵里面,然后去跑floyd就好了

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    double x1,y1,x2,y2;
    double lx,ly,nx,ny;
    int cnt=0;
    double X[250],Y[250];
    double len[250];
    double dp[250][250];
    double dis(double x,double y,double xx,double yy){
        return sqrt((x-xx)*(x-xx)+(y-yy)*(y-yy));
    }
    int main()
    {
        for(int i=0;i<250;i++)
            for(int j=0;j<250;j++)
                if(i==j)dp[i][j]=0;
                else dp[i][j]=1e9;
        cin>>x1>>y1>>x2>>y2;
        cnt++;X[0]=x1,Y[0]=y1;
        while(cin>>nx>>ny){
            int st=cnt;
            len[cnt]=0;
            X[cnt]=nx,Y[cnt]=ny;
            for(int i=0;i<cnt;i++)
            {
                dp[cnt][i]=min(dp[cnt][i],dis(nx,ny,X[i],Y[i])/1000.0*6);
                dp[i][cnt]=min(dp[i][cnt],dis(nx,ny,X[i],Y[i])/1000.0*6);
            }
            cnt++;
            while(cin>>lx>>ly){
                if(lx==-1&&ly==-1)break;
                swap(lx,nx);
                swap(ly,ny);
                len[cnt]=dis(lx,ly,nx,ny)+len[cnt-1];
                X[cnt]=nx,Y[cnt]=ny;
                for(int i=0;i<cnt;i++)
                {
                    dp[cnt][i]=min(dp[cnt][i],dis(nx,ny,X[i],Y[i])/1000.0*6);
                    dp[i][cnt]=min(dp[i][cnt],dis(nx,ny,X[i],Y[i])/1000.0*6);
                }
                for(int i=st;i<cnt;i++)
                {
                    dp[cnt][i]=min(dp[cnt][i],(len[cnt]-len[i])/4000.0*6);
                    dp[i][cnt]=min(dp[i][cnt],(len[cnt]-len[i])/4000.0*6);
                }
                cnt++;
            }
        }
        X[cnt]=x2,Y[cnt]=y2;
        for(int i=0;i<=cnt;i++){
            for(int j=0;j<=cnt;j++){
                if(i==j)dp[i][j]=0;
                else dp[i][j]=min(dp[i][j],dis(X[i],Y[i],X[j],Y[j])/1000.0*6);
            }
        }
        for(int k=0;k<=cnt;k++){
            for(int j=0;j<=cnt;j++){
                for(int i=0;i<=cnt;i++)
                    dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]);
            }
        }
        printf("%.0f
    ",dp[0][cnt]);
    }
    

    Problem M. A multiplication game

    题意

    一开始数是1,两人在玩博弈论,该一个人的时候,就让他乘上2~9中的一个数,如果这个数大于等于p就胜利。

    题解

    直接dfs搜吧,感觉上状态很小的样子

    代码

    #include<bits/stdc++.h>
    using namespace std;
    long long n;
    map<long long,int>H;
    int dfs(long long o){
        if(H[o])return H[o]-1;
        if(o>=n)return 1;
        int flag = 1;
        for(int i=2;i<=9;i++)
            if(dfs(o*1ll*i))
                flag=0;
        H[o]=flag+1;
        return flag;
    }
    int main()
    {
        while(cin>>n)
        {
            if(n==1){
                cout<<"Stan wins."<<endl;
                continue;
            }
            H.clear();
            int o=dfs(1);
            if(o==0)cout<<"Stan wins."<<endl;
            else cout<<"Ollie wins."<<endl;
        }
    }
  • 相关阅读:
    dmo4解析xml
    myeclise生成webservice客户端代码
    华为QOS原理及配置
    【转载】 Jointwave零延时视频传输for FPGA/ASIC进入军工领域
    【转载】 网络性能测试工具
    【转载】 结构体大小计算
    【转载】 H264的I/P/B帧类型判断
    【转载】 IP实时传输协议RTP/RTCP详解
    【转载】 了解实时媒体的播放(RTP/RTCP 和 RTSP)
    【转载】 CSDN博客与博客园使用对比
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5968005.html
Copyright © 2020-2023  润新知