A. Game
You are playing a very popular computer game. The next level consists of n consecutive locations, numbered from 1 to n, each of them containing either land or water. It is known that the first and last locations contain land, and for completing the level you have to move from the first location to the last. Also, if you become inside a location with water, you will die, so you can only move between locations with land.
You can jump between adjacent locations for free, as well as no more than once jump from any location with land i to any location with land i+x, spending x coins (x≥0).
Your task is to spend the minimum possible number of coins to move from the first location to the last one.
Note that this is always possible since both the first and last locations are the land locations.
Input
There are several test cases in the input data. The first line contains a single integer t (1≤t≤100) — the number of test cases. This is followed by the test cases description.
The first line of each test case contains one integer n (2≤n≤100) — the number of locations.
The second line of the test case contains a sequence of integers a1,a2,…,an (0≤ai≤1), where ai=1 means that the i-th location is the location with land, and ai=0 means that the i-th location is the location with water. It is guaranteed that a1=1 and an=1.
Output
For each test case print a single integer — the answer to the problem.
这道题用双指针就可以求出0~0的边界,注意特判
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N =102;
int a[N];
int cnt;
int main()
{
int T;
cin>>T;
int res=0;
while(T--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
int l=1,r=n;
while((l<=n)&&(a[l]==1))l++;
while((r>=1)&&(a[r]==1))r--;
if(l>r)puts("0");
else cout<<r-l+2<<endl;
}
return 0;
}
B. Game of Ball Passing
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Daniel is watching a football team playing a game during their training session. They want to improve their passing skills during that session.
The game involves n players, making multiple passes towards each other. Unfortunately, since the balls were moving too fast, after the session Daniel is unable to know how many balls were involved during the game. The only thing he knows is the number of passes delivered by each player during all the session.
Find the minimum possible amount of balls that were involved in the game.
Input
There are several test cases in the input data. The first line contains a single integer t (1≤t≤5⋅104) — the number of test cases. This is followed by the test cases description.
The first line of each test case contains one integer n (2≤n≤105) — the number of players.
The second line of the test case contains a sequence of integers a1,a2,…,an (0≤ai≤109), where ai is the number of passes delivered by the i-th player.
It is guaranteed that the sum of n over all test cases doesn’t exceed 105.
Output
For each test case print a single integer — the answer to the problem.
题目分析:
如果只有两个人,且两人的传球次数只有一次,那么第一个拿球的人a先传给b,b再传回a,那么两人的次数都被消耗,但如果出现人c,假设a还有传球次数,那么a就可以传给c,且c不增加传球次数,a可以多消耗一次。
那么,不妨让传球次数最多的人先拿球,那么用最大的一项去消耗其他比他次数少的人,这样能贪心(局部最优解)
贪心提出假设:如果max⋅2 ≤ sum,我们总是可以证明我们只能使用一个球。 对于其他情况,球的数量就是2⋅max−sum。
证明结论:为了方便证明,不妨将a1~an从小到大排序,最大的数为an,利用反证法:如果2*max>sum的话就能够让其他数字内部消化(即能够互相传球达到消消乐的效果)。又因为max=an,同时减去an,得max>sum[n-1] 那么利用之前1对1 的结论总有一个点会大于等于1,假设不成立(注意,如果有一个点为1,那么还是可以传给其它人)因此逆否命题也可以求出。
AC代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N =1e5+3;
typedef long long LL;
int a[N];
int cnt;
LL sum;
int main()
{
int T;
cin>>T;
int res=0;
while(T--)
{
int n;
cin>>n;
sum = 0;
int maxn=0;
for(int i=0;i<n;i++)
{
cin>>a[i];
maxn = max(maxn,a[i]);
sum +=a[i];
}
if(sum == 0)cout<<0<<endl; //特判一下
else
{
if(2 * maxn<=sum)cout<<1<<endl;
else
{
cout<<2*maxn - sum<<endl;
}
}
}
return 0;
}