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

Posted subject

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

 

 

 

以上是关于UCF Local Programming Contest 2017(2020-04-06)的主要内容,如果未能解决你的问题,请参考以下文章

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

UCF Local Programming Contest 2012(Practice)补题

UCF Local Programming Contest 2016正式赛

UCF Local Programming Contest 2016 3.29

UCF Local Programming Contest 2015(Practice)个人分析

UCF Local Programming Contest 2012(Practice)