文章目录
A.Cards for Friends
题目大意
给你一张卡片如果一边是偶数就可以cut切开成两半,是奇数就不能切,问能不能切够成为n张。
C++代码
#include<iostream>
using namespace std;
int main()
{
int t;
cin >> t;
int w,h,n;
while(t--)
{
cin >> w >> h >> n;
int res = 1;
while(w%2==0) res*=2,w/=2;
while(h%2==0) res*=2,h/=2;
if(res < n)cout << "NO" << endl;
else cout << "YES" << endl;
}
return 0;
}
B.Fair Division
题目大意
给你一堆硬币,面值只有一元和两元的,我们要分给A和B,并且要求将钱平分,若能平分则YES;不能则NO
C++代码
#include<iostream>
using namespace std;
int main()
{
int n,res1,res2;
int t;
cin >> t;
while(t--)
{
res1 = 0,res2 = 0;
int sum = 0,a;
cin >> n;
for(int i = 0; i < n; i ++)
cin >> a,sum += a,a > 1 ? res2++ : res1++;
if(sum & 1 || (res2 & 1 && res1 == 0) )
cout << "NO" << endl;
else
cout << "YES" << endl;
}
return 0;
}
C.Long Jumps
题目大意
给你一个数组a,每个位置都可以是起点,初始化分数为0,每个位置对应的权重(分值)不同,规则为当前分数加上此时所在的数组位置的元素值,然后你的位置会跳到i+a[i],若当前位置大于n则结束比赛,求选择那个起点开始得到的分值最大。
思路:例:1 1 1 1 1
我们可以选择5个不同的起点,若选择1,则一定经过2345的位置,若选择2,则一定经过345的位置,。。。。我们可以定义一个数组f,用来存经过对应位置的分数,通过逆序遍历数组a,在数组f中存储对应位置的分数。达到O(n)时间复杂度。
C++代码
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 2e+5;
int a[N];
long long f[N];
int main()
{
int t,n;
cin >> t;
while(t--)
{
long long maxn = 0;
cin >> n;
for(int i = 0; i < n; i ++)
cin >> a[i];
for(int i = n - 1; i >= 0;i --)
{
f[i] = a[i] + ((i+a[i])>=n ? 0 : f[i+a[i]]);
if(maxn < f[i]) maxn = f[i];
}
cout << maxn << endl;
}
return 0;
}
D.Even-Odd Game
题目大意
简单博弈题,姐姐A和弟弟B玩游戏,给定一堆球(数组),每个球(数组)上的数字的大小代表积分,姐姐先拿球,拿走不放回,最后谁积分最多谁获胜。
积分规则:
- 姐姐A拿球,若姐姐A拿的球的数字为偶数,姐姐累加积分,若为奇数,则不加分,球不放回;
- 弟弟B拿球,若弟弟B拿的球的数组为奇数,弟弟累加积分,若为偶数,则不加分,球不放回。
思路:姐姐弟弟都是选择最优状态,因此用贪心思想,两者都取当前数组内最大值,即“我不加分,也不让你加分”的原则。我们可以将数组降序排序,然后依次分给姐姐弟弟,并依照加分规则,给两人累加积分。
最后比较积分即可。
C++代码
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 2e+5;
long long a[N];
int cmp(int a,int b)
{
return a > b;
}
int main()
{
int t,n;
cin >> t;
while(t--)
{
long long res1 = 0,res2 = 0;
cin >> n;
for(int i = 0; i < n; i ++)
cin >> a[i];
sort(a,a+n,cmp);
for(int i = 0; i < n ; i ++)
{
if( !(i&1) && !(a[i]&1))
res1 += a[i];
if( i&1 && a[i]&1)
res2 += a[i];
}
cout << (res1 >= res2 ? (res1>res2?"Alice":"Tie"):"Bob")<< endl;
}
return 0;
}
E.Correct Placement
题目大意
拍照,低且瘦的A在前面,高且胖的B在后面(即Ah<Bh&&Aw<Bw || Ah<Bw&&Aw<Bh),要求对于每一个A,只需要一个满足要求的B即可。 因为数据中h可能小于w(一个人怎么可能宽度比高度还大呀,离谱。。),我们可以在存储时将大的数存给h,小的数存给w。这样保证我们在遍历时,a[i].h <= a[i+1].h一定成里。然后只需要维护当h相等时w降序就行。
C++代码
#include<iostream>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
const int N = 2e5+5;
int t,n;
ll h,w;
struct fun{
int id;
ll h;
ll w;
ll ans;
}a[N];
int cmp(fun a, fun b)
{
if(a.h != b.h) return a.h < b.h;
else return a.w > b.w;
}
int cmp2(fun a, fun b)
{
return a.id < b.id;
}
int main()
{
cin >> t;
while(t--)
{
memset(a,0,sizeof(a));
cin >> n;
for(int i = 1; i <= n; i ++)
{
a[i].id = i;
a[i].ans = -1;
cin >> h >> w;
a[i].h = max(h,w);
a[i].w = min(h,w);
}
sort(a+1,a+n+1,cmp);
int index = 1;
for(int i = 1; i <= n; i ++)
a[i].w > a[index].w ? a[i].ans = a[index].id :( a[i].w < a[index].w ?index = i:0);
sort(a+1,a+n+1,cmp2);
for(int i = 1; i <= n; i ++)
cout << a[i].ans << " ";
cout << endl;
}
return 0;
}