2018NYIST第二次月賽
阿新 • • 發佈:2019-01-16
思路
把圖形存到字元數組裡,因為數字和字元在儲存中有一定的規律,所以可以通過下標訪問圖形。
程式碼
#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;
}
思路
直接暴力判斷是否是素數,並且直接輸出結果。 如果打表存素數 或者是 把結果存在數組裡到最後再輸出,都會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;
}
思路
輸入字串後 經過計算
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;
}
思路
模擬過程即可
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--<