欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

2020年04月10日UCF Local Programming Contest 2017

程序员文章站 2022-03-10 12:38:55
A. Electric Bill 题意:这一题比较简单,相当于小学的分组函数的计算电力费用的的题型。 题解:签到题。 代码: #include #include #include #define ll long long using nam ......

a. electric bill

题意:这一题比较简单,相当于小学的分组函数的计算电力费用的的题型。

题解:签到题。

代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
int main(){
    int f,e;
    int n;
    cin>>f>>e;
    cin>>n;
    int temp;
    while(n--){
        cin>>temp;
        int ans=0;
        cout<<temp<<" ";
        if(temp<=1000){
            cout<<temp*f<<endl;
        }else{
            cout<<1000*f+(temp-1000)*e<<endl;;
        }
    }
    return 0;
}

b. simplified keyboard

题意:这一题的大概意思就是新组合的字母的排列,给出了字母间相邻的定义。题目给出两个字符串,要你在题目要求的情况下判断这两个字符串属于哪一种类型。

题解:简单签到题,根据题意对那个字符串进行分情况判断,在判断两个字符是否是“邻居”时候,可利用:

net[8][2]={{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,-1},{-1,1}};

进行每个方向的判断。

代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
char arr[3][9]= {{'a','b','c','d','e','f','g','h','i'},
    {'j','k','l','m','n','o','p','q','r'},
    {'s','t','u','v','w','x','y','z','#'}
};
int net[8][2]={{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,-1},{-1,1}};
int check(int r,int c){
    if(r>=0&&r<3){
        if(r==2){
            if(c>=0&&c<=7){
                return 1;
            }
        }else{
            if(c>=0&&c<=8){
                return 1;
            }
        }
    }
    return 0;
}
int app(char a/*主体*/,char b/*客体*/){//是否是相邻的 
    int x,y;
    for(int i=0;i<3;i++){//找到 本尊的位置 
        for(int j=0;j<9;j++){
            if(arr[i][j]==a){
                x=i;
                y=j;
                break;
            }
        } 
    }
    int d=0;
    for(int i=0;i<8;i++){
        int dx=x+net[i][0];
        int dy=y+net[i][1];//这是下一个坐标
        if(check(dx,dy)/*判断坐标是否合法*/){
            if(arr[dx][dy]==b){//相等
            d=1;
            break;
            }else{//不相等 
            }
        } 
    }    
    return d;
}
int main() {
    int n;
    string str1,str2;
    cin>>n;
    while(n--) {
        cin>>str1>>str2;
        int len1=str1.length();
        int len2=str2.length();
        if(len1!=len2) {
            cout<<3<<endl;
        } else { //两者的长度相同  在这里,可能输出 1 ,可能输出 2 ,可能输出 3
            int f=1;
            for(int i=0; i<len1; i++) {
                if(str1[i]!=str2[i]) { //出现了不相等的
                    f=0;
                }
            }
            if(f==1) {
                cout<<1<<endl;
            } else { //可能输出 2 ,可能输出 3
                //以 str1 为基础,寻找它的邻居,或和它本身相邻
                int g=1;//记录是否找到 邻居
                for(int i=0; i<len1; i++) {
                    if(str1[i]==str2[i]) { //若两者相等
                    } else { //两者不相等,找两者相邻
                        g=app(str1[i],str2[i]);
                        if(!g) {
                            break;
                        }
                    }
                }
                if(g) {
                    cout<<2<<endl;
                } else {
                    cout<<3<<endl;
                }
            }
        }
    }
    return 0;
}

c. singin' in the rain

题意:题目的大概意思就是:给出一张cd的歌曲数目,一串喜欢歌曲的序列,通过按下“下一曲”、“上一曲”的按键来改变曲目的播放顺序,要你求,最少要你按多少次才能达到要求。

题解:注意播放顺序的改变规则即可,模拟。

#include<iostream>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
int main(){
    ll n;//样例的数量 
    cin>>n;
    ll t,s;
    while(n--){
        cin>>t/*一张cd上的歌曲的总数*/>>s/*喜欢歌曲的数量*/;
        ll num[10000]={0};
        for(ll i=0;i<s;i++){
            cin>>num[i];//输入喜欢歌曲的序号 
        }//序号输入完毕,下面开始处理啊数据
        ll ans=0;//存储的是答案
        ll tt=num[0];//当前播放歌曲的位置
        //当第一首歌曲播放完之后。
        ll net;//下一首要播放的歌曲
        for(ll i=1;i<s;i++){
            net=num[i];//这是下一首 
            if(net<num[i-1]){//在它之前 
                ans=ans+min(num[i-1]-net+1,t-num[i-1]-1+net);
            }else if(net>num[i-1]){//在之后 
                if(net-num[i-1]==1){//不需要按 
                }else{//需要按 
                    ans=ans+min(net-num[i-1]-1,num[i-1]+(t-net+1));
                }
            }else if(net==num[i-1]){//下一首播放的歌曲和上一首播放的歌曲一样 
                ans++;//往后在按一次 “后退键 ”
                tt=net;//在一次到达原位置 
            }
            //当前歌曲播放完
        }
        cout<<ans<<endl;
    }
    return 0;
}

d. editor navigation

题意:这题是一个最短路的问题,给你两个点的坐标,要你求移动最少的次数到达目的地,创新的是它给出的不是一个“规矩”的矩阵,移动的规则也和正常的题目有点不同,

题解:bfs求最短路,但要注意在确定它的下一个坐标的时候和正常的题型不同。最短路的步数和点的坐标一起整合在一个结构体中。

代码:

#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
int t,n;
int str,stc,enr,enc;
int num[900]={0};
int vis[900][900]={0};
struct node{
    int r,c,cnt;
};
int net[4][2]= {-1,0,1,0,0,-1,0,1};
void bfs(){
    queue<node> q;
    q.push({str,stc,0});
    vis[str][stc]=1;
    memset(vis,0,sizeof(vis));
    while(!q.empty()){
        node p=q.front();
        q.pop();
        int r=p.r;
        int c=p.c;
        int cnt=p.cnt;
        if(r==enr&&c==enc){//找到目标点 
            printf("%d\n",cnt);
            return ;
        }
        for(int i=0;i<4;i++){//遍历四个方向 
            int dr=r+net[i][0];
            int dc=c+net[i][1];
            if(dr>=1&&dr<=n){
                if(i==0||i==1){//上下移动
                    if(dc<=num[dr]&&!vis[dr][dc]){//直来支直去
                        vis[dr][dc]=1;
                        q.push({dr,dc,cnt+1});
                    }
                    if(dc>num[dr]&&!vis[dr][num[dr]]){
                        vis[dr][num[dr]]=1;
                        q.push({dr,num[dr],cnt+1});
                    }
                }else{//左右移动
                    if(dc==-1&&i==2&&r-1>=1){
                        int tr=r-1;
                        int tc=num[tr];
                        if(!vis[tr][tc]){
                            q.push({tr,tc,cnt+1});
                            vis[tr][tc]=1;
                        }
                    }
                    if(dc==num[r]+1&&i==3&&r+1<=n){//这是坐标向右移动,处在最后的一个点移动到下一行的的第一个字符
                        int tr=r+1;
                        int tc=0;
                        if(!vis[tr][tc]){
                            vis[tr][tc]=1;
                            q.push({tr,tc,cnt+1});
                        }
                    }
                    if(dc>=0&&dc<=num[dr]&&!vis[dr][dc]){
                        vis[dr][dc]=1;
                        q.push({dr,dc,cnt+1});
                    }
                }
            }
        }
    }
}
int main(){
    cin>>t;
    while(t--){
       cin>>n;/*总共有几行*/
       for(int i=1;i<=n;i++){
            cin>>num[i];
       }
       cin>>str>>stc>>enr>>enc;
       bfs();
    }
    return 0;
}

e. simple darts

题意:这是一道反三角函数利用的题目,给你一个圆盘,将其划分为w个区域,每个区域的得分各不相同,向其投向n个镖,求出最终得分。

题解:通过计算点到原点的距离,可以判断它属于那个环内,通过计算点与原点的连线和x轴的夹角可以判断它属于内阁楔形--这个的计算方法是:

double gf=atan((y*1.0)/x)*(180.0*1.0/pi);//算出应有的角度

gf是指点(x,y)与x轴所夹的锐角,但要注意当返回的是一个负值时,可以通过增加180度or360度来进行调整,具体增加多少,要根据点所处的象限来判断。

代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<math.h>
#define ll long long
double pi= 3.1415926535898 ;
using namespace std;
double app(double x,double y){
    return sqrt(x*x+y*y);
}
int main(){
    int n,t;
    int w,b,d,s;
    double x,y;
    cin>>n;//样例的数量 
    while(n--){
        cin>>w>>b>>d>>s;
        //圆形平均分成了 w 份
        double cc=360*1.0/w;//每一份的度数
        double tch[25]={0};
        tch[1]=cc;
        for(int i=2;i<=w;i++){
            tch[i]=tch[i-1]+cc;
        }
        cin>>t;
        int ans=0;//存储最终得分 
        //边输入,边处理 
        for(int i=0;i<t;i++){
            scanf("%lf %lf",&x,&y);//输入两个点的坐标
            double len1=app(x,y);
            if(len1<=b){//位于  第一个小圆环中  
                ans=ans+50;
            }else{
                int f=0;//这是放大的倍数
                if(len1>b&&len1<d){
                    f=2;
                }else if(len1>d&&len1<s){
                    f=1;
                }
                //下面关键是判断位于哪一个楔形内 
                double gf=atan((y*1.0)/x)*(180.0*1.0/pi);//算出应有的角度
                //判断是否要选装
                if(x<0&&y>0){//二象限 
                    gf=180+gf;
                }
                if(x<0&&y<0){//三象限 
                    gf=gf+180;
                }
                if(x>0&&y<0){
                    gf=gf+360;
                }
                int gg=0; 
                for(int i=1;i<=w;i++){
                    if(gf<tch[i]){//在这之中 
                        gg=i;
                        break;
                    }
                }
                ans=ans+gg*f;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}