赞
踩
原文链接
这场只写出来了两题,赛后看了下C题,复杂的模拟题,不想写,其实是写不来 。
题意
有三个怪物,每次操作可以使一个敌人扣一滴血,当此次操作为7的倍数次时,改为特殊攻击,使三个怪物都减一点血,问是否能使用特殊攻击同时消灭三个怪物。
解题思路
首先最后要用特殊攻击消灭怪物,所以三只怪物的总血量得是9的倍数,因为每7次操作,怪物一共会掉9点血。然后要考虑在是否有怪物的血量撑不到最后,意思就是会先被特殊攻击给刮死。
例如:1 3 14
是血量之和9的倍数,无论如何攻击,再第一次特殊攻击时,第一个怪物会先被消灭,所以只要当血量最低的怪物的血量>=特殊攻击的次数即可。特殊攻击的次数为血量之和/9。
代码
#include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> #include<ctime> #include<cctype> #include<iostream> #include<algorithm> //#include<chrono> #include<vector> #include<list> #include<queue> #include<string> #include<set> #include<map> //#include<unordered_set> //#include<unordered_map> #define LL long long #define li i<<1 #define ri i<<1|1 using namespace std; inline LL read() { char c=getchar();LL x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } LL t,a[3],sum; bool init(){ if(sum%9) return false; if(a[0]<sum/9) return false; return true; } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); t=read(); while(t--){ a[0]=read(); a[1]=read(); a[2]=read(); sort(a,a+3); sum=a[0]+a[1]+a[2]; if(init()) printf("YES\n"); else printf("NO\n"); } return 0; }
题意
有一个长度为n的数组a,S为所有a[i]之和,让你构造一个数组长度为n的数组b,使得2*SUM(abs(a[i]-b[i]))<=S,且对于任何相邻的两个b[i],b[i+1],要么b[i]|b[i+1],要么b[i+1]|b[i],且b[i]>0。(SUM为求和。a|b的意思为a是b的因子。)
解题思路
比赛时想了好久,全部构造为最大值、最小值、中位数、平均数、众数,全都是错误的想法,最后才比赛快结束了才想出来。
把a数组平分为2堆,无论如何分,一定会有一堆之和>=S/2,另一堆之和<=S/2。想到这里,答案就能出来了。
构造值为这样的b数组:
1、a[2]、1、a[4]、1、a[6]、1 …
这样的数组的SUM(abs(a[i]-b[i]))=(a[1]-1)+(a[3]-1)+(a[5]-1)+…。
再构造这样的数组:
a[1]、1、a[3]、1、a[5]、1 …
这样的数组的SUM(abs(a[i]-b[i]))=(a[2]-1)+(a[4]-1)+(a[6]-1)+…。
因为之前的理论,之中一种构造一定能符合答案。
代码
#include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> #include<ctime> #include<cctype> #include<iostream> #include<algorithm> //#include<chrono> #include<vector> #include<list> #include<queue> #include<string> #include<set> #include<map> //#include<unordered_set> //#include<unordered_map> #define LL long long #define li i<<1 #define ri i<<1|1 using namespace std; inline LL read() { char c=getchar();LL x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } const int maxn=55; LL t,n,a[maxn],ans1[maxn],ans2[maxn]; int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); t=read(); while(t--){ n=read(); LL sum=0; for(int i=1;i<=n;++i){ a[i]=read(); sum+=a[i]; } for(int i=1;i<=n;++i){ if(i&1){ ans1[i]=1; ans2[i]=a[i]; }else{ ans1[i]=a[i]; ans2[i]=1; } } LL flag1=0,flag2=0; for(int i=1;i<=n;++i){ flag1+=abs(a[i]-ans1[i]); flag2+=abs(a[i]-ans2[i]); } if(2*flag1<=sum){ for(int i=1;i<=n;++i) printf("%lld ",ans1[i]); printf("\n"); }else if(2*flag2<=sum){ for(int i=1;i<=n;++i) printf("%lld ",ans2[i]); printf("\n"); } } return 0; }
题意
有一个机器人,在x坐标轴上行走,在0时刻时0位置。之后有n个命令:在t[i]秒时接受到命令,向目标x[i]位置走去。机器人每秒速度为1。当机器人再行走时,遇到新的指令,它将忽略此条指令。设第i条为好的指令,则满足
机器人再时间t[i]到t[i+1]时,走到过x[i]。默认t[n+1]=+∞。问一共有多少个好的指令。(被忽略的指令也能是好的指令)
写不来,模拟起来感觉很复杂。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。