【AcWing-69】第 69 场周赛 题解


零、写在前面

这场比赛笔者认为相对并不难,稍加推理就可以取得很好的成绩(指 \(\text{AK}\)


一、相遇问题

题目网址

一道很简单的小学行程题目

\[t_{\text{甲乙相遇}}= \cfrac{S_{\text{甲}\rightarrow\text{乙}}}{v_{\text{甲}}+v_{\text{乙}}} =\cfrac{|x-y|}{a+b} =\cfrac{y-x}{a+b} \]

(因为题目中保证 \(x<y\),所以 \(|x-y|=y-x\)

\(\cfrac{y-x}{a+b}\) 为整数,就输出它;不然就输出 \(-1\)

#include<bits/stdc++.h>
using namespace std;
inline long long read()//快速读入
{
	long long x=0;
	char ch=getchar();
	while(ch>'9'||ch<'0') ch=getchar();
	while(ch<='9'&&ch>='0') x=x*10+ch-48,ch=getchar();
	return x;
}
signed main()
{
	//freopen("meet.in","r",stdin);
	//freopen("meet.out","w",stdout);
	int T=read();
	while(T--)
	{
		int x,y,a,b,ans;
		x=read(),y=read(),a=read(),b=read();
		ans=(y-x)/(a+b);//计算答案
		if(ans*(a+b)!=(y-x)) printf("-1\n");//不为整数就输出 -1
		else printf("%d\n",ans)//不然输出刚刚计算的值
	}
	return 0;
} 

二、击中战舰

题目网址

我们由题目中发现,\(a\) 个战舰中,每个战舰都会占用 \(b\) 个还没有被精准打击的格子

所以也就是说,我们攻击占用的 \(b\) 个格子中的任意一个都可以击沉一艘战舰,达成题目要求

所以我们每连续 \(b\) 个没被打击的格子记录其任意一个坐标就行

然后记录完以后,我们就得出这些坐标总个数 \(S\) 中,藏有 \(a\) 艘战舰

题目要求我们只需要击中一艘就行,那我们考虑用 鸽巢原理,假设最坏情况前 \(S-a\) 个坐标都没被战舰占据,那第 \(S-a+1\) 发肯定会击中一艘战舰,所以至少要发射的导弹数就是 \(S-a+1\),发射的坐标从这些坐标中随便抽 \(S-a+1\) 个就行

#include<bits/stdc++.h>
using namespace std;
inline long long read()
{
	long long x=0;
	char ch=getchar();
	while(ch>'9'||ch<'0') ch=getchar();
	while(ch<='9'&&ch>='0') x=x*10+ch-48,ch=getchar();
	return x;
}
int n,sum,lon,cf;
bool a[200009],t[200009];
vector<int>warship;
signed main()
{
	//freopen("fight.in","r",stdin);
	//freopen("fight.out","w",stdout);
	n=read(),sum=read(),lon=read(),cf=read();
	int cnt=0;
	for(int i=1;i<=n;i++)
	{
		char c=getchar();
		while(c=='\n') c=getchar();
		a[i]=c-48;
		if((c-48)^1) cnt++;//若该位置为 0,即没被击中,连续个数就加 1
		else cnt=0;//不然就清 0
		if(!(cnt^lon)) cnt=0,warship.push_back(i);//存入数组
	}
	printf("%u\n",warship.size()-sum+1);
	for(int i=0;i<warship.size()-sum+1;i++) printf("%d ",warship[i]);//随便输出 S-a+1 个坐标即可
	return 0;
} 

三、解方程

这道题可以说是 \(\text{Ac Wing}\) 所有月赛中接近于最简单的 \(\text{T3}\) 了(doge

题目网址

我们发现,题目大意是给定一个 非负整数 \(a\),算方程 \(a-a \oplus x -x =0\)非负整数解 的数量

分析:由题目可知,\(a-x=a \oplus x\)

我们把 \(a\)\(x\) 逐位考虑:

\(a\) 的位 \(x\) 的位 \(a \oplus x\) \(a-x\)
\(0\) \(0\) \(0\) \(0\)
\(0\) \(1\) \(1\) \(-1\)
\(1\) \(0\) \(1\) \(1\)
\(1\) \(1\) \(0\) \(0\)

不难发现 \(a\) 的位数上为 \(1\) 时,x 在此为 \(1\)\(0\),而 \(a\) 的位数上为 \(0\) 时,\(x\) 在此只能是 \(0\)

所以根据组合规律,答案就是 \(2^{a \text{中}1\text{的个数}}\)

#include<bits/stdc++.h>
using namespace std;
inline long long read()//快速读入
{
	long long x=0;
	char ch=getchar();
	while(ch>'9'||ch<'0') ch=getchar();
	while(ch<='9'&&ch>='0') x=x*10+ch-48,ch=getchar();
	return x;
}
inline long long count(int u)//统计 u 中 1 的个数
{
	int res=0,p=1;
	do res+=((u&p)>0),p<<=1;
	while(p<=u);
	return res;
}
signed main()
{
	//freopen("equation.in","r",stdin);
	//freopen("equation.out","w",stdout);
	int T=read();
	while(T--) printf("%lld\n",(1ll<<count(read())));//输出
	return 0;
} 

posted @ 2022-09-25 12:30  DreamerX  阅读(22)  评论(0)    收藏  举报