2021牛客寒假算法基础集训营3

比赛链接

2021牛客寒假算法基础集训营3

C.重力坠击

题目描述

在一个二维平面上有 \(n\) 个敌人,第 \(i\) 个敌人可以描述为一个以 \(\left(x_{i}, y_{i}\right)\) 为圆心, \(r_{i}\) 为半径的圆。
你每次可以对一个半径为 \(R\) 的圆范围内进行攻击(圆心自选,但圆心的横纵坐标必须为整数),对于与你攻击范围有 交点的敌人都会被消火。
你总共可以发动 \(k\) 次攻击,问最多能消多少敌人。
输入描述:
第一行以空格分隔的三个整数 \(n, k, R\)
接下来 \(n\) 行每行以空格分隔的三个整数 \(x_{i}, y_{i}, r_{i}\)

$1 \leq n \leq 10 $
$1 \leq k \leq 3 $
$1 \leq r_{i}, R \leq 7 $
\(0 \leq\left|x_{i}\right|,\left|y_{i}\right| \leq 7\)
敌人的位置可能会有重叠。

输出描述:

输出一行一个正整数代表答案。

示例1

输入

3 1 1
0 0 1
7 7 1
-2 0 1

输出

2

说明

只能发动一次攻击,可以攻击圆心为(-1,0)的圆,这样可以消灭第一个和第三个敌人。

解题思路

dfs

直接暴力枚举所有情况即可,这里千万要注意备份数组不能设置为全局变量!!!

  • 时间复杂度:\(O(C_225^k)\)

代码

// Problem: 重力坠击
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/30841/C
// Memory Limit: 524288 MB
// Time Limit: 4000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}


int res,n,k,R;
struct A
{
	int x,y,r;
}a[11];
bool v[11];
void dfs(int x,int y,int cnt,int had)
{
	if(cnt==k)
	{
		res=max(res,had);
		return ;
	}
	if(y==8)x++,y=-7;
	if(x==8)
	{
		res=max(res,had);
		return ;
	}
    bool bv[11];
	memset(bv,0,sizeof bv);
	int c=0;
	for(int i=1;i<=n;i++)
	{
		if(v[i])continue;
		if(((x-a[i].x)*(x-a[i].x)+(y-a[i].y)*(y-a[i].y))<=(R+a[i].r)*(R+a[i].r))bv[i]=v[i]=true,c++;
	}
	dfs(x,y+1,cnt+1,c+had);
	for(int i=1;i<=n;i++)
		if(bv[i])v[i]=false;
	dfs(x,y+1,cnt,had);
	
}
int main()
{
    cin>>n>>k>>R;
    for(int i=1;i<=n;i++)cin>>a[i].x>>a[i].y>>a[i].r;
    dfs(-7,-7,0,0);
    cout<<res;
    return 0;
}

J.加法和乘法

题目描述

有一天牛牛和牛妹在做游戏,规则如下:
桌面上摆着\(n\)张纸牌,每张纸牌上写着一个正整数,由牛牛先手轮流执行以下操作:
\(\text 1.\)如果桌面上只剩一张纸牌,游戏结束,这张纸牌上的数字如果是奇数则牛牛胜利,反之牛妹胜利。
\(\text 2.\)当前行动玩家选择两张纸牌,设上面的数字分别为\(\mathit X,Y\),接下来玩家从加法和乘法中选择一个并应用到这两个数字上,得到结果为\(\mathit Z\),接下来将选择的两张纸牌丢弃,并拿一张新的纸牌放到桌面上,在上面写上\(\mathit Z\)
假设双方均以最优策略行动,最后谁会赢?

输入描述:

第一行一个正整数\(\mathit n\),代表开始的纸牌数。
第二行\(\mathit n\)个空格分隔的正整数\(a_{i}\)代表开始纸牌上的数字。
\(1\leq n \leq 10^{6}\)
\(1\leq a_{i} \leq 10^{9}\)

输出描述:

如果牛牛能赢,输出\(\mathit NiuNiu\),否则输出\(\mathit NiuMei\)

示例1

输入

3
233 2333 23333

输出

NiuMei

示例2

输入

4
1 1 1 1

输出

NiuNiu

解题思路

博弈论

首先需要特判 \(n=1\) 的情况,另外如果最后一次操作是后手操作的话,由于后手总是可以将两个数变为偶数,所以后手必胜;否则如果偶数数量至多为 \(1\),先手必胜,因为如果有偶数的话先手可以消掉这个偶数,如果后手下次再产生(至多一个)偶数,下下轮先手可以再消去,最后的操作在于先手,所以先手必胜;否则如果偶数数量大于等于 \(2\),先手必败,先手每次最多只能消掉一个偶数,而后手可以产生偶数,最后一个数一定是偶数

  • 时间复杂度:\(O(1)\)

代码

// Problem: 加法和乘法
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/9983/J
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

int n,res[2];
int main()
{
    cin>>n;
    int x;
    bool f=false;
    if(n==1)
    {
    	cin>>x;
    	if(x&1)f=true;
    }
    else if(n%2==0)
    {
    	for(int i=1;i<=n;i++)
		{
			cin>>x;
			res[x&1]++;
		}
		if(res[0]<2)f=true;
    }
    puts(f?"NiuNiu":"NiuMei");
    return 0;
}
posted @ 2022-03-23 22:29  zyy2001  阅读(64)  评论(0编辑  收藏  举报