nenuacm 2019 新生训练#5 题解

A - 第几天?  HDU - 2005

题意:给定一个日期,输出这个日期是该年的第几天。

我们直接把该年<m的月份的天数全部加起来再加上d就行了,同时注意判断闰年。

#include<cstdio>

int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int main()
{
	int y,m,d;
	while(scanf("%d/%d/%d",&y,&m,&d)!=EOF)
	{
		int flag=0,ans=0;
		if ((y%4==0 && y%100!=0) || y%400==0) flag=1;
		for (int i=1;i<m;i++)
		{
			if (i==2 && flag==1) ans++;
			ans+=a[i];
		}
		ans+=d;
		printf("%d\n",ans);
	}
}

B - 时间日期格式转换 POJ - 3751

题意:将24小时制的时间转成12小时制

注意输入输出的小技巧

 

#include<cstdio>

int main()
{
	int y,m,d,t;
	scanf("%d",&t);
	while(t--)
	{
		int pm,hour,minute,second;
		scanf("%d/%d/%d-%d:%d:%d",&y,&m,&d,&hour,&minute,&second); // 对于/ - 这种字符我们可以直接写在输入里 
		if (hour>=12) 
		{
			pm=1;
			hour-=12;
		}
		else pm=0;
		if (hour==0) hour=12;
		printf("%02d/%02d/%d-",m,d,y); // 02d 表示不足两位的话添0凑齐,比如1的话会变成01 
		printf("%02d:%02d:%02d",hour,minute,second); 
		if (pm==1) printf("pm\n");
		else printf("am\n");
	}
}

C - What day is it  HDU - 2133

题意:2007年11月17日 是星期六,给你个日期问你这天是星期几。

我们可以暴力地遍历。直接去算给定的时间和这一天的天数差。

不过这题有比较巧的解法

按2007年11月17日来算太过繁琐,因为公元0001年1月1日是星期一,这样计算就简单了很多。

我们直接计算给定的日期与01年1月1日的差值即可。

最后注意判断不合法的日期。

#include<bits/stdc++.h>
using namespace std;

int a[13] = {0,31,29,31,30,31,30,31,31,30,31,30,31}; // 处理闰年的每月天数 
int b[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; // 处理非闰年的每月天数 
char s[8][10] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}; // 把日期处理成一个数组 
int judge(int y) // 判断闰年 
{
	if ((y%4==0 && y%100!=0) || y%400==0) return 1;
	return 0;
}
int main()
{
	int y,m,d;
	while(scanf("%d%d%d",&y,&m,&d)!=EOF)
	{
		int flag=judge(y);
		if (flag==0 && (m>13 || d>b[m] || m<=0 || d<=0)) { cout<<"illegal"<<endl; continue; }
		if (flag==1 && (m>13 || d>a[m] || m<=0 || d<=0)) { cout<<"illegal"<<endl; continue; }
		int ans=0;
		for (int i=1;i<y;i++)
		{
			if (judge(i)==1) ans+=366;
			else ans+=365;
		}
		for (int i=1;i<m;i++)
		{
			if (flag==1) ans+=a[i];
			else ans+=b[i];
		}
		ans+=d;
		ans%=7;
		cout<<s[ans]<<endl;
	}
}

D - 18岁生日 HDU - 1201 

题意:给定一个人的出生日期,求出他到18岁生日所经过的总天数。

#include<math.h>
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 155

int judge(int y)
{
    if( (y%4==0)&&(y%100!=0) || y%400==0 )return 1;
    else return 0;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int ans=0;
        int y,m,d;
        scanf("%d-%d-%d",&y,&m,&d);
        if(judge(y)&&m==2&&d==29)
        {
            cout<<-1<<endl;
            continue;
        }
        for(int i=y;i<y+18;i++)
        {
            if(judge(i)) ans+=366;
            else ans+=365;
        }
        if(judge(y) && m>=3) ans--;
        if(judge(y+18) && m>=3) ans++;
        cout<<ans<<endl;
    }
    return 0;
}

 

E - 游船出租 HDU - 1861

这题直接模拟一下借船和还船的过程就好了

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

const int maxn=1e2+50;
int vis[maxn];// vis 记录当前的船是否被借 0 没借 1 借了 
int a[maxn]; // a 记录借船时的时间 
int main()
{
    int num=0,x;
    double ans=0;
    while(scanf("%d",&x)&&x!=-1)
    {
        char op;
        int h,m;
        scanf(" %c%d:%d",&op,&h,&m);
        if (x==0)
        {
            if (num==0) cout<<0<<" "<<0<<endl;
            else printf("%d %.0f\n",num,ans*1.0/num);
            num=0; ans=0;
            memset(a,0,sizeof(a));
            memset(vis,0,sizeof(vis));
            continue;
        }
        if (op=='S')
        {
            vis[x]=1;
            a[x]=h*60+m;
        }
        if (op=='E' && vis[x]==1)
        {
            num++;
            ans+=h*60+m-a[x];
            vis[x]=0;
        }
    }
}

G - Specialized Four-Digit Numbers  POJ - 2196 

题意:求出所有满足 (十进制下各位数字之和=十二进制下各位数字之和=十六进制下各位数字之和) 的4位数。

直接把每一个数转成10进制,12进制,16进制。再把对应各位数之和加起来判断是否符合即可

#include<cstdio>

int a[100];
int turn(int n,int r)
{
    int sum=0;
    while(n!=0)
    {
        sum+=n%r;
        n/=r;
    }
    return sum;
}
int judge(int n)
{
    int a=turn(n,10);
    int b=turn(n,12);
    int c=turn(n,16);
    if (a==b && b==c) return 0;
    return -1;
}
int main()
{
    for (int i=1000;i<=9999;i++)
    {
        if (judge(i)==0) printf("%d\n",i);
    }
}

H - 进制转换  HDU - 2031 

题意:输入一个十进制数N,将它转换成R进制数输出。

这个直接转就好了。注意>10进制的输出字符。

#include<cstdio>

void turn(int n,int r)
{
    if (n==0) return;
    int k=n%r;
    n/=r;
    turn(n,r);
    if (k>=10) printf("%c",'A'+k-10);
    else printf("%d",k);
}
int main()
{
    int n,r;
    while(scanf("%d%d",&n,&r)!=EOF)
    {
        if (n<0)
        {
            printf("-");
            n=-n;
        }
        turn(n,r);
        printf("\n");
    }
}

I - The Moronic Cowmpouter POJ - 3191 

题意:将十进制数转成-2进制数

思路:将十进制转换成-2进制,原理也类似于短除法。但不是直接取模,我们处理出来的余数如果是正的就正常存储。如果是负数。需要 余数+2; 商=(商-现在的余数(已经是正的了))/-2;

最后倒序输出

#include<cstdio>

const int maxn=1e2;
int ans[maxn];
int main()
{
	int n,cnt=0;
	scanf("%d",&n);
	while(n!=0)
	{
		int p=n%-2;
		if (p<0) 
		{
			n=(n+p)/-2;
			ans[++cnt]=p+2;
		}
		else 
		{
			n/=-2;
			ans[++cnt]=p;
		}
	}
	for (int i=cnt;i>=1;i--)
		printf("%d",ans[i]);
	if (cnt==0) printf("0");
}

J - Basically Speaking  POJ - 1546

题意:16进制内的进制互相转化

对于a进制转b进制,我们都可以讲a进制转成10进制,再将10进制转成b进制。直接模拟整个过程即可

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;

char s[100],n;
string ans;
void turn(int sum,int r)
{
    while(sum!=0)
    {
        int k=sum%r;
        if (k>=10) ans+='A'+k-10;
        else ans+=k+'0';
        sum/=r;
        n++;
    }
}
int main()
{
    int a,b;
    while(scanf("%s",&s)!=EOF)
    {
        scanf("%d%d",&a,&b);
        int len=strlen(s)-1;
        int cnt=0;
        int sum=0;
        for (int i=len;i>=0;i--)
        {
            if (s[i]>='A' && s[i]<='Z') sum+=(s[i]-'A'+10)*pow(a,cnt);
            else sum+=(s[i]-'0')*pow(a,cnt);
            cnt++;
        }
        n=0;
        ans="";
        turn(sum,b);
        if (n>7)
        {
            printf("  ERROR\n");
            continue;
        }
        for (int i=1;i<=7-n;i++)
            printf(" ");
        for (int i=n-1;i>=0;i--)
            cout<<ans[i];
        printf("\n");
    }
}

 

K - decimal system HDU - 2106

题意:给出n个数x,每个数是在y进制下的,求出所有数转成10进制后的和

思路:把每个数转成十进制然后求和即可

#include<cstdio>
#include<cmath>
#include<iostream>
using namespace std;
int turn(int n,int r)
{
    int sum=0,cnt=0;
    while(n!=0)
    {
        sum+=(n%10)*pow(r,cnt);
        cnt++;
        n/=10;
    }
    return sum;
}
int main()
{
    int t;
    while(scanf("%d",&t)!=EOF)
    {
        int sum=0;
        while(t--)
        {
            int n,r;
            scanf("%d(%d)",&n,&r);
            sum+=turn(n,r);
        }
        printf("%d\n",sum);
    }
}

L - Sky数 HDU - 2097 

题意:给你一个数,判断是否 十进制下各位数之和=十二进制下各位数之和=十六进制下各位数之和

和上面的G题类似

#include<cstdio>

int a[100];
int turn(int n,int r)
{
    int sum=0;
    while(n!=0)
    {
        sum+=n%r;
        n/=r;
    }
    return sum;
}
int judge(int n)
{
    int a=turn(n,10);
    int b=turn(n,12);
    int c=turn(n,16);
    if (a==b && b==c) return 0;
    return -1;
}
int main()
{
    int n;
    while(scanf("%d",&n)&&n)
    {
        if (judge(n)==0) printf("%d is a Sky Number.\n",n);
        else printf("%d is not a Sky Number.\n",n);
    }
}

M - Bitset HDU - 2051

题意:将十进制数转成二进制

#include <cstdio>

using namespace std;

int a[100];
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int cnt=0;
        while(n!=0)
        {
            a[++cnt]=n%2;
            n/=2;
        }
        for (int i=cnt;i>=1;i--)
            printf("%d",a[i]);
        printf("\n");
    }
}

N - Basic remains POJ - 2305

题意: 在b进制下,求p%m,再转化成b进制输出。其中p为b进制大数1000位以内,m为b进制数9位以内

p的位数太大,我们可以用高精度模拟,其实也可以不需要。

先将p,m转化成十进制,再求p%m,避免出现大数据,处理p的时候边处理边取模。

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

const int maxn=1e5+50;
char p[maxn],m[maxn];
void dg(int pp,int b)
{
	if (pp==0) return;
	dg(pp/b,b);
	printf("%d",pp%b);
}
int main()
{
	int b;
	while(scanf("%d",&b)&&b)
	{
		scanf("%s%s",p,m);
		int len1=strlen(m);
		int mm=0;
		for (int i=0;i<len1;i++)
		{
			mm*=b;
			mm+=m[i]-'0';
		}
		int len2=strlen(p);
		int pp=0;
		for (int i=0;i<len2;i++)
		{
			pp*=b;
			pp+=p[i]-'0';
			pp%=mm;
		}
		if (pp==0) cout<<pp;
		else dg(pp,b);
		cout<<endl;
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值