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

Original title address: https://www.jisuanke.com/contest/7195?view=challenges

A. Electric Bill

Topic: Hierarchical charging, power consumption below 1000, one above, ask how much should be paid

AC code:

#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

Topic: Given an alphabet, then given two strings, ask the type of the two strings.

1: Same length and same letter

2: The length is the same, the letters are not exactly the same, but different letters are adjacent

3: Not belonging to 1 and 2

Idea: First deal with the adjacent relationship of the alphabet, and then traverse by one.

Use map <char, string> keys as letters, and the values ​​are adjacent letters;

AC code:

#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];int
    }        }zuo xia//

     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

Topic: Give a playlist order, each time you listen to the last song, you need to press the previous or next song until you reach the first song you listen to. How many buttons need to be pressed

思路:每两个之间分别计算,向前一首需要按的次数,和向后一首需要按的次数,取较小值即可,注意的是听完歌曲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

 

 

 

Guess you like

Origin www.cnblogs.com/subject/p/12682865.html