• UCF Local Programming Contest 2017(2020-04-06)


    原题地址:https://www.jisuanke.com/contest/7195?view=challenges

    A. Electric Bill

    题意:分级收费,用电1000以下一档,以上一档,问应支付多少钱

    AC代码:

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int main(){
        int a,b,n,temp;
        cin>>a>>b;
        cin>>n;
        for(int i=0;i<n;i++){
            cin>>temp;
            int ans=0;
            if(temp>1000){
                ans=1000*a+(temp-1000)*b;
            }else{
                ans=temp*a;
            }
            cout<<temp<<" "<<ans<<endl;
        }
        return 0;
    } 
    View Code

    B. Simplified Keyboard

    题意:给定一个字母表,再给定两个字符串,问两字符串的类型。

    1:长度相同,字母也相同

    2:长度相同,字母不完全相同,但不同的字母是相邻的

    3:不属于1和2的

    思路:先预先处理字母表的相邻关系,在按个遍历。

    用map<char,string> 键为字母,值为相邻字母;

    AC代码:

    #include<bits/stdc++.h>
    #include<iostream>
    #include<vector>
    #include<queue>
    #include<string>
    #include<list>
    #include<set>
    #include<map>
    #include<stack>
    # define PI 3.14159265358979323846
    using namespace std;
    typedef long long ll;
    const int maxn = 1010;
    ll node[maxn];
    char flag[3][10]={"abcdefghi","jklmnopqr","stuvwxyz0"};
    map<char,string> mp;
    int main()
    {
        for(int i=0;i<3;i++)
        {
            for(int j=0;j<9;j++)
            {
                if(j+1<9&&flag[i][j+1]>='a'&&flag[i][j+1]<='z') mp[flag[i][j]]+=flag[i][j+1];//you
                if(i+1<3&&flag[i+1][j]>='a'&&flag[i+1][j]<='z') mp[flag[i][j]]+=flag[i+1][j];//xia
                if(i-1>=0&&flag[i-1][j]>='a'&&flag[i-1][j]<='z') mp[flag[i][j]]+=flag[i-1][j];//shang
                if(j-1>=0&&flag[i][j-1]>='a'&&flag[i][j-1]<='z') mp[flag[i][j]]+=flag[i][j-1];//zuo
                if(i-1>=0&&j+1<9&&flag[i-1][j+1]>='a'&&flag[i-1][j+1]<='z') mp[flag[i][j]]+=flag[i-1][j+1];//you shang
                if(i+1<3&&j+1<9&&flag[i+1][j+1]>='a'&&flag[i+1][j+1]<='z') mp[flag[i][j]]+=flag[i+1][j+1];// you xia
                if(i-1>=0&&j-1>=0&&flag[i-1][j-1]>='a'&&flag[i-1][j-1]<='z') mp[flag[i][j]]+=flag[i-1][j-1];//zuo shang
                if(i+1<3&&j-1>=0&&flag[i+1][j-1]>='a'&&flag[i+1][j-1]<='z') mp[flag[i][j]]+=flag[i+1][j-1];//zuo xia
            }
        }
        int n;
        cin>>n;
        while(n--)
        {
            string s1,s2;
            cin>>s1>>s2;
            if(s1==s2)cout<<1<<endl;
            else if(s1.length()==s2.length())
            {
                int f = 1;
                for(int i=0;i<s1.length();i++)
                {
                    char t1 = s1[i];
                    char t2 = s2[i];
                    if(t1==t2) continue;
                    if(mp[t1].find(t2)==string::npos)
                    {
                        f = 0;
                        break;
                    }
                }
                if(f) cout<<2<<endl;
                else cout<<3<<endl;
            }
            else cout<<3<<endl;
        }
        
        return 0;
     } 
    View Code

    C. Singin' in the Rain

    题意:给出一个歌单顺序,每次听完上一首歌后需要通过按上一曲或下一曲直至达到下一首要听的歌,问要听完整个给出的歌单顺序,需要按多少次按钮

    思路:每两个之间分别计算,向前一首需要按的次数,和向后一首需要按的次数,取较小值即可,注意的是听完歌曲n后会自动调到n+1,如果听完后按下一首,此时应该是第n+2首

    AC代码:

     

    #include<bits/stdc++.h>
    #include<iostream>
    #include<vector>
    #include<queue>
    #include<string>
    #include<list>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    typedef long long ll;
    const int maxn = 1e3+10;
    ll node[maxn];
    int main()
    {
        int N;
        cin>>N;
        while(N--)
        {
            ll t,s;
            cin>>t>>s;
            for(int i=0;i<s;i++)
            {
                cin>>node[i];
            }
            ll sum = 0;
            for(int i=1;i<s;i++)
            {
                ll a = (node[i-1]+1)%t;
                ll b = node[i];
                if(a<b)
                {
                    ll ans1 = b-a;
                    ll ans2 = a+(t-b);
                    sum+=min(ans1,ans2);
    //                cout<<"1:"<<min(ans1,ans2)<<endl;
                }
                else if(a>b)
                {
                    ll ans1 = (t-a)+b;
                    ll ans2 = a-b;
                    sum+=min(ans1,ans2);
    //                cout<<"2:"<<min(ans1,ans2)<<endl;
                }
            
            }
            cout<<sum<<endl;
            
         } 
        return 0;
    }    
    View Code

     

    D. Editor Navigation

    题意:word 里边有几行字母,给定初始位置和目标位置,问光标最少移动几次

    思路:BFS但要注意 光标在首尾和上下移动时字母长度不同的情况

    AC代码:

    #include<bits/stdc++.h>
    #include<iostream>
    #include<vector>
    #include<queue>
    #include<string>
    #include<list>
    #include<set>
    #include<map>
    #include<stack>
    # define PI 3.14159265358979323846
    using namespace std;
    typedef long long ll;
    const int maxn = 1010;
    const int N = 125,M = 85;
    int T,n,bx,by,ex,ey,num[N];
    bool vis[N][M];
    int dit[4][2] = {-1,0,1,0,0,-1,0,1};
    struct node
    {
        int x,y,cnt;//cnt 表示移动次数 
    };
    void BFS()
    {
        queue<node>q;
        q.push({bx,by,0});
        memset(vis,0,sizeof(vis));
        vis[bx][by] = 1;
        while(!q.empty())
        {
            node tmp = q.front();
            q.pop();
            int x = tmp.x;
            int y = tmp.y;
            int cnt = tmp.cnt;
            
            if(x==ex&&y==ey)
            {
                cout<<cnt<<endl;
                return ;
            }
            for(int i=0;i<4;i++)
            {
                int nx = x+dit[i][0];
                int ny = y+dit[i][1];
                if(nx>=1&&nx<=n)
                {
                    if(i==0||i==1)//上下移动时 
                    {
                        if(ny<=num[nx]&&!vis[nx][ny])//没有超出范围
                        {
                            vis[nx][ny]=1;
                            q.push({nx,ny,cnt+1});
                         } 
                         if(ny>num[nx]&&!vis[nx][ny])//超出范围 
                         {
                             vis[nx][num[nx]]=1;
                             q.push({nx,num[nx],cnt+1});
                         }
                    }
                    else//左右 
                    {
                        if(ny==-1&&i==2&&x-1>=1)//在开头,左移则移动到上层末尾
                        {
                            int tx = x-1;
                            int ty = num[tx];
                            if(!vis[tx][ty])
                            {
                                vis[tx][ty]=1;
                                q.push({tx,ty,cnt+1});
                            }
                         } 
                         if(ny==num[x]+1&&i==3&&x+1<=n)
                         {
                             int tx = x+1;
                             int ty = 0;
                             if(!vis[tx][ty])
                             {
                                 vis[tx][ty]=1;
                                 q.push({tx,ty,cnt+1});
                             }
                         }
                         if(ny>=0&&ny<=num[x]&&!vis[nx][ny])
                         {
                             vis[x][ny]=1;
                             q.push({x,ny,cnt+1});
                         }
                    }
                    
                }
            }
            
            
        }
        
        
    }
    int main()
    {
        
        int T;
        cin>>T;
        while(T--)
        {
            cin>>n;
            for(int i=1;i<=n;i++)
            {
                cin>>num[i];
            }
            cin>>bx>>by>>ex>>ey;
            BFS();
        }
        return 0;
    } 
    View Code

    E. Simple Darts

    题意:给定一个圆形靶,分成w份扇形,每个扇形又分成三部分,分别给出b,d,s,分别为靶心,双倍区,单倍区。给定落点问最终得分。

    思路:求出得分需要知道在几倍区和所在区的序号

    通过求距离可知在几倍区

    atan2函数可以算出与x轴正方向的夹角

    AC代码:

    #include<bits/stdc++.h>
    #include<iostream>
    #include<vector>
    #include<queue>
    #include<string>
    #include<list>
    #include<set>
    #include<map>
    #include<stack>
    # define PI 3.14159265358979323846
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5+10;
    double node[maxn];
    int w,b,d,s;
    double flen(double x,double y) //计算点到原点的距离 
    {
        double a = x*x;
        double b = y*y;
        return sqrt(a+b);
    }
    double fans(double x,double y)//计算 点与原点组成直线与x正方向的角度 
    {
        return  atan2(y,x)*180/PI;//范围是-180到180; 
    }
    int main()
    {
        ll N;
        cin>>N;
        while(N--)
        {
            cin>>w>>b>>d>>s;
            double tt = 360*1.0/w; //将圆分成w份 
            
            node[1] = tt;//node记录每份的角度边界 
            for(ll i=2;i<=w;i++)
            {
                node[i] = node[i-1]+tt; 
            } 
            
    
            
    //        d=b+d;
    //        s=d+s;
            ll t;
            cin>>t;
            ll sum = 0;
            while(t--)
            {
                
                ll flag=0;
                double x,y;
                cin>>x>>y;
                double len = flen(x,y);
    //            cout<<len<<" ";
                //通过距离算出 是单环还是双环还是圆心 
                if(len<b) flag=1;
                else if(len<d) flag=2;
                else if(len<s) flag=3;
                if(flag==1) 
                {
                    sum+=50;
                    
    //                cout<<"!1:50"<<endl; 
                } 
                    
                 
                if(flag==2)
                {
                    double tans = fans(x,y);//角度 
                    if(tans<0) tans = 360+tans;// 负数角度变成正数 
                    
                    
                    ll f = 1;
                    //循环 找到 所处哪个 楔形块 
                    for(f;f<=w;f++) 
                    {
                        if(node[f]>tans) break;
                    }
                    sum+=2*f;
    //                cout<<"!2:"<<f<<endl;
                }
                if(flag==3)
                {
                    double tans = fans(x,y);
                    if(tans<0) tans = 360+tans;
                
                    ll f = 1;
                    for(f;f<=w;f++)
                    {
                        if(node[f]>tans) break;
                    }
                    sum+=f;
    //                cout<<"!3:"<<f<<endl;
                }
            }
            cout<<sum<<endl;
            
        }
            
         
        return 0;
    }    
    View Code

     

     

     

  • 相关阅读:
    透视校正插值
    投影矩阵推导
    编程思想-小即是美
    Win10使用小技巧
    TotalCommander 之 快捷键
    TotalCommander 之 配置
    TotalCommander 之 日常使用技巧
    上士闻道,勤而行之;中士闻道,若存若亡;下士闻道,大笑之。不笑不足以为道。
    《诫子书》
    青春不是年华,而是心境
  • 原文地址:https://www.cnblogs.com/subject/p/12682865.html
Copyright © 2020-2023  润新知