2019山东省赛复现 2020/9/28
A - Calandar
题意:
规定一个星球上的一年有12个月,一个月30天,输入第一行是一个日期和当天是星期几,第二行是另一个日期,要求输出这个日期是星期几。
因为30能整除5,因此每个月都是一样的,不用考虑两个日期的大小和年月。
1、求两个日期的差值:如d2>d1直接d2-d1,否则d2+30-d1
2、求第一行已知的那天是周几就让差值加几
3、求出的这个差值对5取余就是要求的星期几
using namespace std;
#define ll long long
#define speed_up ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
ll t;
cin>>t;
while(t--){
ll y1,m1,d1;
cin>>y1>>m1>>d1;
string a;
int day,day2;
cin>>a;
ll y2,m2,d2;
cin>>y2>>m2>>d2;
if(a=="Monday")day=1;
if(a=="Tuesday")day=2;
if(a=="Wednesday")day=3;
if(a=="Thursday")day=4;
if(a=="Friday")day=5;
if(d2>d1)day2=d2-d1;
else day2=d2+30-d1;
day=day+day2;
day=day%5;
if(day==0) cout<<"Friday"<<endl;
if(day==1) cout<<"Monday"<<endl;
if(day==2) cout<<"Tuesday"<<endl;
if(day==3) cout<<"Wednesday"<<endl;
if(day==4) cout<<"Thursday"<<endl;
}
}
C - Wandering Robot
题意:
机器人从原点(0,0)开始按U(上)D(下)L(左)R(右)四个方向移动,给出字符串的长度n,按照字符串循环的次数k,求直到循环结束,机器人走到的最远的距离(距离指的是这个点到原点的x+y的值)。
因为没有想到第一个循环有可能就是最远的情况,比赛一直wa也没找到错在哪。
1、先找到第一个循环的最末点坐标,求出最大距离
2、然后找到最后一个循环的最末点坐标:每一个循环的最末点坐标(x,y)一定是延直线延伸的,是第一次循环最末点的倍数,用第一个循环的坐标乘循环次数就行
3、比较第一个循环和最后一个循环最大距离值,输出那个大的
4、注意用fabs求绝对值
using namespace std;
#define ll long long
int main()
{
ll t;
cin>>t;
while(t--)
{
cin>>n>>k;
string s;
cin>>s;
ll x=0,y=0,xn=0;
for(int i=0; i<n; i++)
{
if(s[i]=='U')
y++;
if(s[i]=='D')
y--;
if(s[i]=='L')
x--;
if(s[i]=='R')
x++;
{
xn=fabs(x)+fabs(y);//xn是第一次循环的最远距离最大长度
}
}
ll sumy=(k-1)*y;
ll maxx=0;
for(ll i=0; i<n; i++)
{
if(s[i]=='U')
sumy++;
if(s[i]=='D')
sumy--;
if(s[i]=='L')
sumx--;
if(s[i]=='R')
sumx++;
if(maxx<fabs(sumx)+fabs(sumy))
{
maxx=fabs(sumx)+fabs(sumy);//maxx是最后一次循环的最远距离最大长度
}
}
cout<<max(xn,maxx)<<endl;
}
}
D - Game on a Graph
已知有两个队1和2,输入k个队员的顺序和一个n个点m条线的连通图,按顺序每个队员去掉一条边,当去掉一条边后构不成连通图时,这个队就输了,另一队赢。
连通图要保证每个点都连有一条边,即最少要有n-1条边,开始有m条边,则可以去掉的边有m-n+1条,去到m-n+1条时,这个队就赢了
注意对k取模,有可能队员循环操作好几次
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define speed_up ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int main()
{
speed_up;
int t;
cin>>t;
while(t--)
{
int k,n,m;
string s;
cin>>k>>s>>n>>m;
for(int i=0;i<m;i++)
{
int a,b;
cin>>a>>b;//不用考虑哪个边连哪个点
}
if(s[(m-n+1)%k]=='1')cout<<2<<endl;
else cout<<1<<endl;
}
}
F - Stones in the Bucket
有n堆个数不相等的石头,每一步可以对石头进行两种操作,一是将其中一堆的一个石头转移到另一堆,二是将其中一堆的一个石头去掉,求让所有堆的石头数目都相等最少要几步。
因为大的给小的分1和大的直接减1用的步数相同但可以更快的达到个数相等,找出平均数,把小于平均数的用大于平均数的部分补成平均数,这时候剩下的部分就是多出来的要去掉的,最后把这两种情况加和
using namespace std;
#define ll long long
#define speed_up ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int main()
{
speed_up;
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
int a[n];
ll num=0;
for(int i=0;i<n;i++)
{
cin>>a[i];
num+=a[i];
}
ll num1,num2;
num1=num/n;//平均数
num2=num%n;//多余的要去掉的石子数
ll num3=0;//大的分给小的需要的步数
for(int i=0;i<n;i++){
if(a[i]<num1){
num3+=num1-a[i];
}
}
num3+=num2;
cout<<num3<<endl;
}
}