A:Maya Calendar
这题主要是理解题目意思,理解后就是简单的时间转化。大体意思:
Haab日历有19个月(分别有名字),前面18个月每个月有20天,只有一个月只有5天(0-4),一年一共有365天。
Tzolkin日历只要求出具体是哪一天,因为它的天是由数字+字符一起表示的,而且是相对唯一。前面的数字每13,循环一次,即使到下个月下年,继续循环,而字符则固定不变,1-20天后面的字符串一样。
所以求出第一种日历一共记录了多少天,然后转为为第二种日历。把总天数模13得到T日历前面的数字,总天数模20得到后面的字符,最后求出是多少年,T日历一共20*13天。注意求年的时候如果模等于0,但是不需要进位(WA了一次。
AC代码 G++:
#include<stdio.h>
#include<string.h>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#define Max 1010
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
using namespace std;
map<string,int > m;
char names[][10]={"imix","ik","akbal","kan","chicchan","cimi","manik","lamat", "muluk", "ok","chuen", "eb", "ben", "ix", "mem", "cib", "caban","eznab","canac", "ahau"};
void init() //直接求出第一种各个月份有多少天
{
m["pop"]=0;
m["no"]=20;
m["zip"]=40;
m["zotz"]=60;
m["tzec"]=80;
m["xul"]=100;
m["yoxkin"]=120;
m["mol"]=140;
m["chen"]=160;
m["yax"]=180;
m["zac"]=200;
m["ceh"]=220;
m["mac"]=240;
m["kankin"]=260;
m["muan"]=280;
m["pax"]=300;
m["koyab"]=320;
m["cumhu"]=340;
m["uayet"]=360;
}
/*
1
4. uayet 0
*/
int main()
{
init();
int n,laji;
int day;
char month[10];
int year,temp;
int all_days;
string M;
scanf("%d",&n);
printf("%d\n",n); //奇葩输出格式
while(n--)
{
all_days=0;
scanf("%d.%s%d",&day,month,&year);
M=month;
all_days=day+1+m[M]+year*365;//总共的天数
temp=all_days%13;
if(temp) //13一个循环,如果模等于0 则是13
day=temp;
else day=13;
laji=all_days%20;
if(laji)
laji--;
else
laji=19; //最后一个,因为月份从0开始
if(all_days%260==0) //刚好是最后一天
year=all_days/260-1;
else
year=all_days/260;
printf("%d %s %d\n",day,names[laji],year); //注意输出顺序
}
return 0;
}
B:Color Me Less
水题,根据题目意思,每次遍历所有的点,找到最小的(如果是0,直接可以输出)。
AC代码 G++:
#include<stdio.h>
#include<string.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<math.h>
#include<stack>
#include<map>
#define Max 1010
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
using namespace std;
int a[20][3];
int main()
{
int r,g,b;
for(int i=0;i<16;i++)
{
scanf("%d%d%d",&a[i][0],&a[i][1],&a[i][2]);
}
int ans;
int min,temp;
while(scanf("%d%d%d",&r,&g,&b)!=EOF&&r!=-1&&g!=-1&&b!=-1)
{
min=9999999; //初始化最大
for(int i=0;i<16;i++)
{
temp=(r-a[i][0])*(r-a[i][0])+(g-a[i][1])*(g-a[i][1])+(b-a[i][2])*(b-a[i][2]);
if(temp<min)
{
ans=i;
min=temp;
if(!temp)
break;
}
}
printf("(%d,%d,%d) maps to (%d,%d,%d)\n",r,g,b,a[ans][0],a[ans][1],a[ans][2]);
}
return 0;
}
C: Flip and Shift
简单数学题:给出一个序列,问是否可以把所有1(黑色的点)放在一起,是一个圈!
观察得到:
1、如果圈是奇数,每个都可以经过变化到达任何位置,所以这种一定是YES,
2、如果是偶数,需要把所有的1放在一起,但是奇数点只能变到奇数地方,偶数点只能变的偶数地方,要想输出YES,那么1的奇数点和偶数点之差不能大于1.否则中间已经夹了0。可以画图验证下。
AC代码:
#include<stdio.h>
#include<string.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#define Max 20
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
using namespace std;
int main()
{
int odd,dou;
int n,m,temp,flag;
scanf("%d",&n);
while(n--)
{
scanf("%d",&m);
odd=0;
dou=0;
flag=0;
if(m%2) flag=1; //奇数其实直接可以输出了
for(int i=1;i<=m;i++)
{
scanf("%d",&temp);
if(temp) //黑色
{
if(i%2)
{
odd++; //记录奇数
}
else
dou++; //记录偶数
}
}
if(flag||abs(odd-dou)<=1)
{
printf("YES\n");
}
else
printf("NO\n");
}
return 0;
}
E:THE DRUNK JAILER
简单模拟题,先把所有情况求出来,然后问一个答一个。
#include<stdio.h>
#include<string.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#define Max 110
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
using namespace std;
int a[Max];
int ans[Max]; //记录答案
void init()
{
ans[1];
int sum=1; //它前面有多少个可以逃跑
for(int i=2;i<=100;i++)
{
if(a[i]) //关的
{
a[i]=0;
sum+=1; //把自己算上去
ans[i]=sum; //记录答案
}
else
{
a[i]=1;
ans[i]=sum;
}
for(int j=i*2;j<=100;j+=i)
{
a[j]=~a[j];//取反
}
}
}
int main()
{
int n,temp;
init();
scanf("%d",&n);
while(n--)
{
scanf("%d",&temp);
printf("%d\n",ans[temp]);
}
return 0;
}
F:Self Numbers
题目问有哪些数不是Self_Number,我们把所有的SelfNUm,q求出来,不是就输出,暴力水过。
AC代码 G++:
#include<stdio.h>
#include<string.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#define Max 10000
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
using namespace std;
int a[Max+50];
int Self_num(int temp) //求该数可以生成哪个Self_Num
{
int ans=temp;
while(temp)
{
ans+=temp%10;
temp/=10;
}
return ans;
}
void init()
{
for(int i=1;i<Max;i++)
{
if(!a[i]) //没有生成就输出
{
printf("%d\n",i);
}
a[Self_num(i)]=1;
}
}
int main()
{
init();
return 0;
}
G:Integer Inquiry 大整数相加,附送大整数加减乘除
AC代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<queue>
#include<algorithm>
#define Max 110
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
using namespace std;
int sum[Max];
void add(int num[])
{
int flag=0;
sum[0]=max(sum[0],num[0]);
int i;
for(i=1;i<num[0];i++)
{
sum[i]+=num[i]+flag;
if(sum[i]>=10)
{
sum[i]%=10;
flag=1;
}
else flag=0;
}
while(flag)
{
sum[i]+=flag;
if(sum[i]>10)
{
sum[i]%=10;
flag=1;
i++;
}
else flag=0;
}
if(i>sum[0])
sum[0]=i;
}
void show(int a[]) //不想改了,睡午觉了,烂点能过就好
{
int i=102;
while(!a[i]) i--;
for(;i>=1;i--)
{
printf("%d",a[i]);
}
printf("\n");
}
int main()
{
char cnum[110];
int num[110];
int i,cnt;
while(scanf("%s",cnum)!=EOF)
{
if(strlen(cnum)==1&&cnum[0]=='0')
{
show(sum);
break;
}
i=0;
cnt=1;
memset(num,0,sizeof(num));
while(cnum[i]&&cnum[i]=='0') i++;//去0
for(int j=strlen(cnum)-1;j>=i;j--) //反着存
{
num[cnt++]=cnum[j]-'0';
}
num[0]=cnt;
add(num);
}
return 0;
}
大整数减法:
/*大整数减法*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define Max 1005
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
/*memcpy(b, a, len * sizeof(float));*/
void char_to_int(char c_num[],int big_num[]);
void sub_bignum(char c_num1[],char c_num2[]);
void show(int a[]);
int big_num1[10010],big_num2[10100];
int big_ans[10500]; //答案
char c_num1[10050],c_num2[10005];
void show1(int a[]) //低》》高
{
for(int i=1;i<=a[0];i++)
{
printf("%d",a[i]);
}
printf("\n");
}
int main()
{
scanf("%s%s",c_num1,c_num2);
sub_bignum(c_num1,c_num2);
return 0;
}
int bigger(char c_num1[],char c_num2[])
{
int num1=strlen(c_num1),num2=strlen(c_num2);
if(num1>num2)
return 1;
else if(num1<num2)
return -1;
else
{
num1=strcmp(c_num1,c_num2);
if(num1>0)
return 1;
else if(num1==0)
return 0;
else
return -1;
}
}
void sub_bignum(char c_num1[],char c_num2[]) //低位到高位,1-n,第0位为字符串的长度 前面永远是大的吧
{
char_to_int(c_num1,big_num1);
char_to_int(c_num2,big_num2);
int n=bigger(c_num1,c_num2);
int flag;
if(n==0)
{
printf("0\n");
return;
}
else if(n>0) //前面大
{
flag=1; //开始为正
n=big_num1[0];
}
else
{
flag=0;
n=big_num2[0];
printf("-");
}
int tem_num=0,laji=0;
// n=max(big_num1[0],big_num2[0]); //选最大的一位数作为高位
big_ans[0]=n; //最高的那位
for(int i=1;i<=n;i++)
{
if(flag) //第一个数大
{
tem_num=big_num1[i]-big_num2[i]+laji;
if(tem_num<0) //
{
tem_num+=10;
big_ans[i]=tem_num;
laji=-1;
}
else
{
big_ans[i]=tem_num;
laji=0;
}
}
else
{
tem_num=big_num2[i]-big_num1[i]+laji;
if(tem_num<0) //
{
tem_num+=10;
laji=-1;
big_ans[i]=tem_num;
}
else
{
big_ans[i]=tem_num;
laji=0;
}
}
}
show(big_ans);
}
void char_to_int(char c_num[],int big_num[]) //字符》》数组 第0位表示数组的大小
{
int num=1,count=strlen(c_num);
for(int i=count-1;i>=0;i--) //低位》》高位
{
big_num[num++]=c_num[i]-'0';
}
big_num[0]=count;
}
void show(int a[]) //逆序输出
{
int n=a[0];
while(a[n]==0)
{
n--;
}
while(n>=1)
{
printf("%d",a[n--]);
}
printf("\n");
}
大整数乘法:
/*乘法*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define Max 2100
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
/*大精度模板(个人),输入两个字符串,结果在big_ans,没有考虑-1的情况哦*/
void char_to_int(char c_num[],int big_num[]);
void multiplication(char c_num1[],char c_num2[]);
void show(int a[],int n);
int big_num1[2100],big_num2[2100];
int big_ans[50000]; //答案
char c_num1[2005],c_num2[2005];
int main()
{
scanf("%s%s",c_num1,c_num2);
multiplication(c_num1,c_num2);
return 0;
}
void multiplication(char c_num1[],char c_num2[]) //输入两个字符数组,结果保存在big_ans
{
char_to_int(c_num1,big_num1); //存储从 0》》-1 低位到高位
char_to_int(c_num2,big_num2);
// show(big_num1);
// show(big_num2);
int tem_num,count;
for(int i=0;big_num1[i]!=-1;i++)
{
for(int j=0;big_num2[j]!=-1;j++)
{
tem_num=big_num1[i]*big_num2[j];
count=(i+j+1);//直接存放的位置
while(tem_num)
{
big_ans[count]+=(tem_num%10);
count++;
tem_num/=10;
}
}
}
show(big_ans,strlen(c_num1)+strlen(c_num2));
}
void char_to_int(char c_num[],int big_num[]) //字符》》数组
{
int num=0,count=strlen(c_num);
for(int i=strlen(c_num)-1;i>=0;i--)
{
big_num[num++]=c_num[i]-'0';
}
big_num[num]=-1;//-1表示结束了
}
void show(int a[],int n) //需要进位
{
int laji=0,m;
for(int i=1;i<=n;i++)
{
if(a[i]+laji>=10)
{
m=a[i]+laji;
laji=m/10;
a[i]=m%10;
}
else
{
a[i]+=laji;
laji=0;
}
}
// printf("数字为:");
while(a[n]==0)
{
n--;
if(n==0)
{
printf("0\n");
return;
}
}
// n--;
while(n)
{
printf("%d",a[n--]);
}
// if(a[n+1]!=0)
// printf("%d",a[n+1]);
printf("\n");
}
除法:
/*除法*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#define Max 2005
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
/*大精度模板(个人),输入两个字符串,结果在big_ans,没有考虑-1的情况哦*/
void division(int big_num1[],int num); //高精除 int
void char_to_int(char c_num[],int big_num[]);
void multiplication(char c_num1[],char c_num2[]);
void show(int a[]);
int big_num[Max]; //
int big_num1[2100],big_num2[2100];
int big_ans[50000]; //答案
int big_dis[50000];
char c_num1[2005],c_num2[2005];
using namespace std;
int main()
{
int num;
scanf("%s%d",c_num1,&num);
char_to_int(c_num1,big_num1);
division(big_num1,num);
return 0;
}
void division(int big_num1[],int num)//
{
int tem_num=0,count=big_num1[0];
big_dis[0]=count;
for(int i=big_num1[0];i>=1;i--)
{
big_dis[i]=((tem_num*10+big_num1[i])/num);
tem_num=(tem_num*10+big_num1[i])%num;
}
show(big_dis);
}
void char_to_int(char c_num[],int big_num[]) //字符》》数组
{
int num=1,count=strlen(c_num);
for(int i=count-1;i>=0;i--) //低位到高位
{
big_num[num++]=c_num[i]-'0';
}
big_num[0]=count;//第0位表示多少位数
}
void show(int a[]) //需要进位
{
int n=a[0];
while(a[n]==0) //去前导0
n--;
a[0]=n;
if(n==0)
{
printf("0\n");
return;
}
while(n>0)
{
printf("%d",a[n--]);
}
printf("\n");
}
H:Doubles
水题,给出序列,有没有数是序列里面的2倍。
AC代码:
#include<stdio.h>
#include<string.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#define Max 1000
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
using namespace std;
int a[Max];
int ans;
void fun(int num)
{
if(a[num]) //如果有数的两倍是它,记录
{
ans++;
if(a[num*2]) //如果它的两倍的数存在
ans++;
else
a[num*2]=1;
}
else{
a[num]=1;
if(a[num*2])
ans++;
else
a[num*2]=1;
}
}
int main()
{
int n=0;
int temp;
while(scanf("%d",&temp)!=EOF)
{
if(temp==-1) break;
ans=0;
memset(a,0,sizeof(a));
fun(temp);
while(scanf("%d",&temp)&&temp)
{
fun(temp);
}
printf("%d\n",ans);
}
return 0;
}
I:Gold Coins
问能获得多少金币。全部算出,然后问一个答一个,暴力水。
#include<stdio.h>
#include<string.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#define Max 15010
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
using namespace std;
int a[Max];
void init()
{
int sum=0;
int cnt=1;
for(int i=1;i<=145;i++)
{
for(int j=0;j<i;j++)
{
sum+=i;
a[cnt++]=sum;
}
}
}
int main()
{
int n;
init(); //全部枚举,数据较小
while(scanf("%d",&n)!=EOF&&n)
{
printf("%d %d\n",n,a[n]);
}
return 0;
}
J:Speed Limit
超级水题;
#include<stdio.h>
#include<string.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#define Max 1010
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
using namespace std;
int main()
{
int n;
while(scanf("%d",&n)!=EOF&&n!=-1)
{
int m=0;
int s,t1,t=0;
for(int i=0;i<n;i++)
{
scanf("%d%d",&s,&t1);
m+=s*(t1-t);
t=t1;
}
printf("%d miles\n",m);
}
return 0;
}
K:IP Address
模拟求解就好了
#include<stdio.h>
#include<string.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<math.h>
#include<map>
#define Max 1010
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
using namespace std;
void change(char *num) //把字符转为为
{
int cnt=0;
for(int i=0;num[i];i++)
{
cnt+=int(pow(2,7-i))*(num[i]-'0');
}
printf("%d",cnt);
}
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
char temp[10];
char num[40];
scanf("%s",num);
int cnt=0;
for(int i=0;num[i];i++)
{
if(cnt!=8)
{
temp[cnt]=num[i];
cnt++;
}
else
{
temp[cnt]='\0';
change(temp);
if(num[i])
printf(".");
temp[0]=num[i];
cnt=1;
}
}
temp[cnt]='\0';
change(temp);
printf("\n");
}
return 0;
}
L:Goldbach's Conjecture
M:Sum of Consecutive Prime Numbers
N:Dirichlet's Theorem on Arithmetic Progressions
上面这几题都是素数筛选类似,M题可能麻烦点,需要记录前缀和,然后剪枝。
欧拉筛选素数。或者直接百度素数帅选:
int a[100000]
void init()
{
a[1]=1;
int n=sqrt(Max);
for(int i=2;i<=n;i++) //所有枚举范围,有时候不能,因为需要遍历所有的数,这里可以
{
if(!a[i]) //没有标记过素数
{
a[i]=0;
for(int j=i*2;j<=Max;j+=i) //后面必须是Max,否则无法筛选后面的数
{
a[j]=1;
}
}
}
}
懂这个这几题就差不多了,就贴个M题的算法,差不多算暴力,枚举了所有的情况,然后保存答案,特别注意缩小范围,题目只给了10000,大于10000直接pass,不然超时。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<map>
#include<algorithm>
#define Max 10000
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
using namespace std;
int prim[Max+10]; //素数的个数
int ans[Max+10]; //答案
int a[Max+10];
int cnt; //素数的个数
int sum[Max+10]; //前缀和
void init()
{
a[1]=1;
int Sum=0;
for(int i=2;i<=Max;i++)
{
if(!a[i])
{
Sum+=i; //前缀
prim[cnt]=i;
sum[cnt+1]=Sum;
cnt++;
for(int j=i*2;j<=Max;j+=i)
{
a[j]=1;
}
}
}
int num;
for(int i=1;i<=cnt;i++)
{
for(int j=i;j<=cnt;j++)
{
num=sum[j]-sum[j-i];
if(num>10000) //过滤 否则会超时
break;
ans[num]++;
}
}
}
int main()
{
int n;
init();
while(scanf("%d",&n)!=EOF&&n)
{
printf("%d\n",ans[n]);
}
return 0;
}
O:POJ 3094
简单题;
AC代码:
#include<stdio.h>
#include<string.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#define Max 1010
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
using namespace std;
int main()
{
char mes[260];
int ans;
while(1)
{
ans=0;
gets(mes);
if(mes[0]=='#')
break;
for(int i=0;mes[i];i++)
{
if(mes[i]=='\n') break;
if(mes[i]==' ')
continue;
ans=ans+(mes[i]-'A'+1)*(i+1);
}
printf("%d\n",ans);
}
return 0;
}
P:Humidex
这题也不难,但是注意几点:
exp(x)就是e的多少次方,C <math.h> 里面有,log(x),就是以e为底的log,math.h 里面也有,简直不要太爽。
AC代码,最shadiao的方法:
#include<stdio.h>
#include<string.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#define Max 1010
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
#define e 2.718281828
using namespace std;
double Dew_h(double dew) //把dew 变成 题目给出的h
{
double h;
h=(6.11*exp(5417.7530*((1/273.16) - (1/(dew+273.16))))-10)*0.5555;
return h;
}
double H_dew(double h) //题目的h,变成Dew
{
double dew;
dew=(h/0.5555+10.0)/6.11;
dew=log(dew);
dew=1/(1/273.16-dew/5417.7530)-273.16;
return dew;
}
int main()
{
char one,two;
double num1,num2;
while(scanf("%c",&one)!=EOF)
{
if(one=='E') break;
scanf("%lf %c %lf\n",&num1,&two,&num2);
if(one=='T'&&two=='D')
{
double ans=Dew_h(num2)+num1;
printf("T %.1f D %.1f H %.1f\n",num1,num2,ans);
}
else if(two=='T'&&one=='D')
{
double ans=Dew_h(num1)+num2;
printf("T %.1f D %.1f H %.1f\n",num2,num1,ans);
}
else if(one=='T'&&two=='H')
{
double ans=num2-num1;
ans=H_dew(ans);
printf("T %.1f D %.1f H %.1f\n",num1,ans,num2);
}
else if(two=='T'&&one=='H')
{
double ans=num1-num2;
ans=H_dew(ans);
printf("T %.1f D %.1f H %.1f\n",num2,ans,num1);
}
else if(two=='H'&&one=='D')
{
double ans=Dew_h(num1);
ans=num2-ans;
printf("T %.1f D %.1f H %.1f\n",ans,num1,num2);
}
else
{
double ans=Dew_h(num2);
ans=num1-ans;
printf("T %.1f D %.1f H %.1f\n",ans,num2,num1);
}
}
return 0;
}