2018NYIST第二次月赛

A 1530 riba2534的拷问2

思路

把图形存到字符数组里,因为数字和字符在存储中有一定的规律,所以可以通过下标访问图形。

代码
#include <cstdio>
#include <cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char picturn[7][70]=
{
    {"#####....############...##########################............... "},
    {"#...#....#....#....##...##....#........##...##...#..#............ "},
    {"#...#....#....#....##...##....#........##...##...#..#.......##### "},
    {"#...#....##########################....#####################..... "},
    {"#...#....##........#....#....##...#....##...#....#..#.......##### "},
    {"#...#....##........#....#....##...#....##...#....#..#............ "},
    {"#####....###########....###########....###########............... "},
};
int get_index(int num)//根据一个对应的整数值或字符的ASCII码返回在picturn中对应的首列
{
    if(num<=9&&num>=0)
        return 5*num;
    if((char)num=='+')
        return 50;
    else if(char(num)=='-')
        return 55;
    else
        return 60;
}
int ans_index[20];
int total;
int main()
{
    int ca;
    scanf("%d",&ca);
    while(ca--)
    {
        total=0;
        int a,c,sum;
        char b;
        scanf("%d%c%d",&a,&b,&c);
        if(b=='-')
            sum=a-c;
        else
            sum=a+c;
        ans_index[total++]=get_index((int)a);
        ans_index[total++]=get_index((int)b);
        ans_index[total++]=get_index((int)c);
        ans_index[total++]=get_index((int)'=');
        if(sum<0)//结果为负数时 先把负号加上 并且把sum改为绝对值 
        {
             ans_index[total++]=get_index((int)'-');
             sum*=-1;
        }
        if(sum/10)//有十位 加上十位
        {
            ans_index[total++]=get_index((int)sum/10);
            sum%=10;
        }
        ans_index[total++]=get_index((int)sum);
        for(int i=0;i<7;++i)//控制行
        {
            for(int k=0;k<total;++k)//控制列
            {
                if(k)
                    printf(".");
                int now_index=ans_index[k];
                for(int j=0;j<5;++j)
                    printf("%c",picturn[i][now_index+j]);
            }
            printf("\n");
        }
        puts("");
    }
    return 0;
}


B 1517 神奇的环

思路

相邻两数互质,1与任何数互质,所以输入n输出n即可。

代码
#include <stdio.h>

int main()
{
    int n;
    scanf("%d",&n);
    printf("%d\n",n);
    return 0;
}

C 1525 日期判断

思路

正常方法就一层一层if判断,这里主要介绍新的操作。

对于年乘10000+月乘100+日,这样直接大小进行判断,年的优先级会更高,如果年相同自然就判断月,月相同则判断日。这样乘的好处还有不会爆int,根据输入,年月日也互不干扰。

由于输入格式是统一可以存在前导0的,直接用strcmp比较字符串也可以

代码1:
#include <stdio.h>

int main()
{
    int t, a, b, c, aa, bb, cc;
    for(scanf("%d",&t); t; --t)
    {
        scanf("%d-%d-%d",&a,&b,&c);
        aa = a*10000+b*100+c;
        scanf("%d-%d-%d",&a,&b,&c);
        bb = a*10000+b*100+c;
        scanf("%d-%d-%d",&a,&b,&c);
        cc = a*10000+b*100+c;
        printf("%s\n", bb <= aa && aa <= cc ? "YES" : "NO");
    }
    return 0;
}

代码2:一层一层if判断

#include<map>
#include<cstdio>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int flag=0;
        int a_y,a_m,a_d;
        int b_y,b_m,b_d;
        int c_y,c_m,c_d;
        scanf("%d-%d-%d %d-%d-%d %d-%d-%d",&a_y,&a_m,&a_d,&b_y,&b_m,&b_d,&c_y,&c_m,&c_d);
        if(a_y>b_y)
        {
            if(a_y<c_y)
                flag=1;
            else if(a_y==c_y)
            {
                if(a_m<c_m)
                    flag=1;
                else if(a_m==c_m)
                {
                    if(a_d<=c_d)
                        flag=1;
                    else
                        flag=0;
                }
                else
                    flag=0;
            }
            else
                flag=0;
        }
        else if(a_y==b_y)
        {
            if(a_y<c_y)
            {
                if(a_m>b_m)
                    flag=1;
                else if(a_m==b_m)
                {
                    if(a_d>=b_d)
                        flag=1;
                    else
                        flag=0;
                }
                else
                    flag=0;
            }
            else if(a_y==c_y)
            {
                if(a_m>b_m)
                {
                    if(a_m<c_m)
                        flag=1;
                    else if(a_m==c_m)
                    {
                        if(a_d<=c_d)
                            flag=1;
                    }
                    else
                        flag=0;
                }
                else if(a_m==b_m)
                {
                    if(a_m<c_m)
                    {
                        if(a_d>=b_d)
                            flag=1;
                        else
                            flag=0;
                    }
                    else if(a_m==c_m)
                    {
                        if(a_d>=b_d&&a_d<=c_d)
                            flag=1;
                    }
                }
                else
                    flag=0;
            }
            else  //a_y>c_y
                flag=0;
        }
        else  //a_y<b_y
            flag=0;
        if(flag)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}
	

D 1518 跳高比赛

思路

中学物理。。。 首先求出运动时间t,然后利用x=vt-(gt^2)/2; (因为是向上做减速运动,所以是 -);

代码
#include<stdio.h>
using namespace std;
#define g 10
int main()
{
    int s, h, vx, vy;
    while(~scanf("%d %d %d %d",&s,&h,&vx,&vy))
    {
        int t = s / vx ;
        int high = vy * t- (g * t * t ) / 2;
        if( high >= h)
            printf("Win!\n");
        else
            printf("Lose!\n");
    }
    return 0;
}

E 1450 wzy的刁难1

思路

直接暴力判断是否是素数,并且直接输出结果。 如果打表存素数 或者是 把结果存在数组里到最后再输出,都会RE

代码
#include<math.h>
#include<cstdio>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
int is_prime(int val)  //判断素数
{
    if(val<2)
        return 0;
    int k=sqrt(val);
    for(int i=2; i<=k; ++i)
    {
        if(val%i==0)
            return 0;
    }
    return 1;
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        int flag=0;   //是否有素数
        int t;    //代替n
        int tmp;
        int ans=0;
        if(is_prime(n))
        {
            if(!flag)
                printf("YES\n");
            flag=1;
            printf("%d\n",n);
        }
        while(n/10)
        {
            t=n;
            while(t)
            {
                tmp=t%10;
                ans+=tmp;
                t/=10;
            }
            n=ans;
            if(is_prime(ans))
            {
                if(!flag)
                    printf("YES\n");
                flag=1;
                printf("%d\n",ans);
            }
            ans=0;
        }
        if(!flag)
            printf("NO\n");
    }
    return 0;
}


F 1489 电话号码的个数

思路

输入字符串后 经过计算
k:数字8的个数
len:数字的总个数
那么:
如果 k<len/11
​ 最多组成k个电话号码
else len/11<=k
​ 最多可以组成len/11个电话号码
所以答案是 min(k,len/11)

代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=5100;
char str[maxn];
int main()
{
    int len;
    int k;//记录字符8出现的次数
    while(~scanf("%d",&len))
    {
        k=0;
        scanf("%s",str);
        for(int i=0;i<len;++i)
            if(str[i]=='8')
                k++;
        int ans=min(k,len/11);
        printf("%d\n",ans);
    }
}

G 1503 啥暴力啊

思路

贪心,能跳到终点则跳到终点,不然选择跳最远不一定最优,因为最远下次跳的不一定比近一点的点更远。

所以无法跳到终点就跳到下次能跳到的最远点

代码
#include <stdio.h>

int v[10005];

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i = 1; i <= n; ++i) scanf("%d",&v[i]);
        int ans = 0, now = 1; // now 表示当前青蛙所在点,ans表示跳跃几次
        while(now <= n) // 如果青蛙点<终点继续查找
        {
            if(v[now]+now > n)
            {
                now = v[now]+now;
                ++ans;
                break;
            }
            int ma = now; // 记录下次能跳最远点下标是哪个
            for(int j = now+1; j <= now+v[now]; ++j)
            {
                if(v[j]+j > v[ma]+ma) ma = j;
            }
            if(ma == now) break; // 表示下次能跳最远点下标找不到,那么就可以退出循环
            now = ma;
            ++ans;
        }
        if(now > n) printf("%d\n",ans);
        else printf("WA\n");
    }
    return 0;
}

H 1532 大吉大利 今晚吃鸡

思路

模拟过程即可

1.把每个枪支的的威力和可装配件个数和配件种类存到结构体内
2.更新每种配件的威力加成
3.遍历每个枪支,计算该枪支的威力,找出最大值即可

代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=510;
struct node{
    double wl;//威力
    int cnt;//多少个配件
    int pj[maxn];//存储配件种类
}wq[maxn];//武器
double total_pj[maxn];
double Solve(int index)//计算下标为index的威力
{
    double k=1.0;
    for(int i=0;i<wq[index].cnt;++i)//枚举每个配件
    {
        k+=total_pj[wq[index].pj[i]];
    }
    return wq[index].wl*k;
}
int main()
{
    int t,n,m;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&n,&m);// n个枪支 m各配件
        for(int i=0;i<n;++i)
        {
            scanf("%lf",&wq[i].wl);
            scanf("%d",&wq[i].cnt);
            for(int j=0;j<wq[i].cnt;++j)
                scanf("%d",&wq[i].pj[j]);
        }
        for(int i=0;i<=500;++i)
            total_pj[i]=0.0;
        while(m--)
        {
            int index;
            double val;
            scanf("%d %lf",&index,&val);
            if(total_pj[index]<val)
                total_pj[index]=val;
        }
        double maxx=0.0;
        for(int i=0;i<n;++i)
        {
            double val=Solve(i);
            if(val>maxx)
                maxx=val;
        }
        printf("%.4lf\n",maxx);
    }
}

I 1526 回文数?回文数!

思路

先判断是否是回文数。 如果不是的话,就模拟加法,然后再判断。

注意清零,消除cun_b数组前面的0;

特判一下110

110+11=121;

代码
#include<map>
#include<cstdio>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
char s[1010];
int a[1010],b[1010],sum[1010];
char cun_a[1010][1010],cun_b[1010][1010],cun_s[1010][1010];  //加数、加数、和
void init()
{
    memset(cun_a,0,sizeof(cun_a));
    memset(cun_b,0,sizeof(cun_b));
    memset(cun_s,0,sizeof(cun_s));
}
int main()
{
    int t,ca=1;
    scanf("%d",&t);
    while(t--)
    {
        init();
        if(ca!=1)
            printf("\n");
        printf("Case %d:\n",ca++);
        scanf("%s",s);
        int ls=strlen(s);
        int cou=0;
        int i=0,j=ls-1,pan=1;
        while(i<j)      //先判断是否是回文串
        {
            if(s[i]!=s[j])
            {
                pan=0;
                break;
            }
            i++;
            j--;
        }
        if(pan==1)     //是
            printf("The number itself is palindrome!\n");
        else      //否
        {
            int time=1;
            while(time<=30)
            {
                time++;
                for(i=0,j=ls-1; i<ls&&j>=0; i++,j--) //转换成整数数组a[],b[],并存下两个加数
                {
                    a[i]=s[i]-'0';
                    cun_a[cou][i]=s[i];
                    b[i]=s[j]-'0';
                    cun_b[cou][i]=s[j];
                }
                for(i=0;i<ls;i++)    //把b数组前面的0清除
                    if(cun_b[cou][i]!='0')
                    break;
                j=0;
                for(;i<ls;i++)
                    cun_b[cou][j++]=cun_b[cou][i];
                cun_b[cou][j]='\0';
                int flag=0;  //进位
                for(i=ls-1,j=0; i>=0; i--,j++)  //从后往前加
                {
                    sum[j]=(a[i]+b[i]+flag)%10;
                    flag=(a[i]+b[i]+flag)/10;
                }
                if(flag)
                {
                    sum[ls++]=flag;
                }
                for(i=0,j=ls-1; i<ls&&j>=0; i++,j--) //存下 和
                {
                    cun_s[cou][i]=sum[j]+'0';
                }
                i=0,j=ls-1,pan=1;
                while(i<j)
                {
                    if(sum[i]!=sum[j])
                    {
                        pan=0;
                        break;
                    }
                    i++;
                    j--;
                }
                if(pan)
                {
                    cou++;
                    break;
                }
                else
                {
                    strcpy(s,cun_s[cou]);
                    cou++;
                }
            }
            if(time>30)
                printf("This number has been converted more than 30 times!\n");
            else
            {
                printf("This number has been transformed into palindrome %d times!\n",cou);
                for(int i=0; i<cou; i++)
                {
                    printf("STEP %d : %s + %s = %s\n",i+1,cun_a[i],cun_b[i],cun_s[i]);
                }
            }
        }
    }
    return 0;
}

J 1529 最小字符串

思路

两边不同则取小,相同需要比较里面。

如样例

4 z c b z

4 z b c z

代码
#include <stdio.h>

char s[2005], ans[2005];

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i = 0; i < n; ++i) scanf(" %c",&s[i]);
        int l = 0, r = n-1, tot = 0;
        while(l <= r)
        {
            if(s[l] == s[r])
            {
                int a = l, b = r;
                while(s[a] == s[b]) ++a, --b;
                if(s[a] < s[b]) ans[tot++] = s[l++];
                else ans[tot++] = s[r--];
            }
            else if(s[l] < s[r]) ans[tot++] = s[l++];
            else ans[tot++] = s[r--];
        }
        ans[n] = '\0'; // 这样可以代替memset,因为输出判断到\0会结束,避免了输出上次残留数据
        printf("%s\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值