【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;
}