牛客杯 - 贪吃的派蒙
贪吃的派蒙
问题描述
在遥远的提瓦特大陆上,正在筹备一年一度的羽球节,猎鹿人餐厅为犒劳认真筹备的众人,准备了K份甜甜花酿鸡供大家排队领取。
在每一次的排队中,编号为i的角色领取上限为Ai,这意味着他可以领取的甜甜花酿鸡在[1-Ai]范围内。当一个角色领完本次的甜甜花酿鸡,他/她就会回到队列的末尾,直到所有甜甜花酿鸡都被吃完为止。当轮到一个角色领取时,如果所有的甜甜花酿鸡都被领完,那么他/她就要帮大家刷盘子。
贪吃的派蒙每次都吃固定的Ax个甜甜花酿鸡(如果剩下的甜甜花酿鸡的数量比Ax小,那么他就把剩下的都吃完)。我们很容易找到派蒙的编号,Ax比其他所有的Ai都要大。大家都想让派蒙最后留下来刷盘子,请你写一个程序来判断这是否可能。
输入输出描述
输入
第一行包含一个整数T(1≤T≤100),表示有T组测试数据。
接下来每组测试数据包含两行。
第一行包含两个整数N和K(2≤N≤10^5,0≤K≤10^8),分别表示人数和甜甜花酿鸡的数量。
第二行包含一个整数Ai(1≤Ai≤10^9),表示队列中编号为i的角色可以领取甜甜花酿鸡的最大数量。始终只有一个最大的Ax。
输出
如果大家能找到一种方案让派蒙刷盘子,那么输出“YES”。否则输出“NO”。
思路
- 分为第一轮和其他轮,第一轮和AX前的那些人有关,其他轮和除AX外所有人有关。
- 判断
- 如果那些人按最多的吃但是吃完剩下的数目还没有他们多那就下轮再整派蒙,这轮就一人吃一个。
- 如果那些人按最多的吃能吃完但是一个一个的吃吃不完那就说明这轮存在一种方法可以让派蒙输。
- 如果那些人一人吃一个的吃都能吃完那就说明派蒙赢了。
代码
#include<iostream>
using namespace std;
typedef struct Demo {
long long pernum;
long long chknum;
long long num[100000];
long long ax=0;
long long axindex = 0;
long long sum = 0;
long long axsum=0;
}Demo;
bool find(Demo demo) {
if (demo.chknum <= demo.axindex + 1) {
return false;
}
else if (demo.chknum - demo.axsum <= demo.ax && demo.chknum - demo.axindex - 1 > 0)
return true;
else
demo.chknum = demo.chknum - demo.axindex - 1 - demo.ax;
//第一轮的判断
while (true) {
//其他轮的循环判断
if (demo.chknum <= demo.pernum) {
return false;
}
else if (demo.chknum - demo.sum <= demo.ax && demo.chknum - demo.pernum > 0)
return true;
else
demo.chknum = demo.chknum - demo.pernum - demo.ax;
}
}
int main() {
int n;
Demo demo[100];
cin >> n;
for (int i = 0; i < n; i++) {
cin >> demo[i].pernum;
cin >> demo[i].chknum;
for (int j = 0; j < demo[i].pernum; j++) {
cin >> demo[i].num[j];
demo[i].sum += demo[i].num[j];
if (demo[i].num[j] > demo[i].ax) {
demo[i].ax = demo[i].num[j];
demo[i].axindex = j;
demo[i].axsum = demo[i].sum - demo[i].ax;
}
}
demo[i].sum -= demo[i].ax;
}
for (int i = 0; i < n; i++) {
if (find(demo[i]))
cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}

浙公网安备 33010602011771号