A. Yet Another String Game
题目传送门:
水题
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
string str;
cin>>str;
for(int i=0;i<str.length();i++)
{
if(i%2==0)
{
if(str[i]!='a') printf("a");
else printf("b");
}
else
{
if(str[i]!='z') printf("z");
else printf("y");
}
}
printf("\n");
}
//system("pause");
return 0;
}
B. The Great Hero
题目传送门:
题目大意:
hero有A点攻击力和B点血量。有n只怪兽,每只怪兽有ai点攻击力和bi点血量。问hero能不能杀死所有怪兽,即使在杀完最后一只怪兽时死完。
思路:
其实这题可以写的非常的简单。
我们可以想到当能杀死怪兽时而又最惨烈的情况那就是hero用最后一滴血,杀死了攻击力最高的怪兽。也就是B - 1 + maxn >= sum (maxn为怪兽的最高攻击力,sum为杀死所有怪兽需要承受的攻击)
AC Code
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e5+10;
LL a[N],b[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
LL p,q;
int n;
LL maxn=0;
scanf("%lld%lld%d",&p,&q,&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
maxn=max(maxn,a[i]);
}
for(int i=1;i<=n;i++)
scanf("%lld",&b[i]);
q=maxn-1+q;
LL sum=0;
int flag=0;
for(int i=1;i<=n;i++)
{
int k=b[i]/p;
if(b[i]%p) k++;
q=q-k*a[i];
if(q<0) flag=1;
}
if(flag==1) printf("NO\n");
else printf("YES\n");
}
//system("pause");
return 0;
}
C. Searching Local Minimum(新颖的二分查找)
题目传送门:
题目大意:
这是一个交互题,你可以查询最多100个位置的数,经过查询之后输出任意一个数 ai < min{ ai−1,ai+1} 的位置。
思路:
我们可以想到当区间中的任意位置有mid。如果a[mid] > a[mid+1],那么区间 [ mid+1 , n ]中一定存在答案,因为a[n+1]为无穷大。那么反之如果a[mid]<a[mid+1] , 那么区间[ 1 , mid ]中一定存在答案。想到这里,再结合数据范围,就很容易想到二分查找。
AC Code
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
int l=1,r=n;
int x,y;
while(l<r)
{
int mid=(l+r)/2;
printf("? %d\n",mid);
fflush(stdout);
scanf("%d",&x);
printf("? %d\n",mid+1);
fflush(stdout);
scanf("%d",&y);
if(x>y) l=mid+1;
else r=mid;
}
printf("! %d",l);
fflush(stdout);
//system("pause");
return 0;
}
D1. Painting the Array I(贪心好题)
题目传送门:
思路:
考虑贪心
我们记当前a0数组最前面的元素为p,a1最前面的元素为q。那么a中的每一个元素,我们依次考虑分配给a0更优还是分配给a1更优。
当p==q时
显然这时候a[i]给到哪个子数组都无所谓。
当p!=a[i]&&q==a[i]
显然把a[i]丢在a0后更优
当q!=a[i]&&p==a[i]
显然把a[i]丢在a1后更优
当one!=two&&one!=a[i]&&two!=a[i]
此时放哪个位置都会让答案加一,那么怎么选择呢??
定义nxt[i]为数字i出现最近的位置
如果 nxt[p] < nxt[q] ,放在p后面更优
如果nxt[p]>nxt[q],放在q后面更优
(这里我的理解是:nxt 即为下一个相同数字的位置,那么 nxt 位置更远的中间就会存在有更多的数可以阻止两者合并,于是我们就先把当前这个数放在 nxt 更近的数后面)
AC Code
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
vector<int>vec[maxn];
int id[maxn],a[maxn],n;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
vec[a[i]].push_back(i);
}
int p=-1,q=-1;
int num=0;
for(int i=1;i<=n;i++)
{
id[a[i]]++;
if(p==q) //如果相等,就随便仍一个。
{
if(p!=a[i])
num++;
p=a[i];
}
else if(p!=a[i]&&q==a[i])
{
p=a[i];
num++;
}
else if(p==a[i]&&q!=a[i])
{
q=a[i];
num++;
}
else
{
if(p==-1)
{
q=a[i];
num++;
}
else if(q==-1)
{
p=a[i];
num++;
}
else
{
int x=n+1,y=n+1;
if(id[p]<vec[p].size()) x=vec[p][id[p]];
if(id[q]<vec[q].size()) y=vec[q][id[q]];
if(x>y) q=a[i];
else p=a[i];
num++;
}
}
}
printf("%d\n",num);
//system("pause");
return 0;
}
D2. Painting the Array II
题目传送门:
方法和上面是一样的,只是各种条件反一下即可
AC Code
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
vector<int>vec[maxn];
int a[maxn],idx[maxn];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
vec[a[i]].push_back(i);
}
int num=0;
int p=-1,q=-1;
for(int i=1;i<=n;i++)
{
idx[a[i]]++;
if(p==q)
{
if(p!=a[i])
num++;
p=a[i];
}
else if(p==a[i]||q==a[i])
continue;
else
{
if(p==-1) p=a[i];
else if(q==-1) q=a[i];
else
{
int x=n+1,y=n+1;
if(idx[p]<vec[p].size()) x=vec[p][idx[p]];
if(idx[q]<vec[q].size()) y=vec[q][idx[q]];
if(x<y) q=a[i];
else p=a[i];
}
num++;
}
}
printf("%d\n",num);
//system("pause");
return 0;
}