A题
题目大意:从原点走到一个给定的点,有五种走的方式分别是向左,向右,向上走,向下走,保持不动,每次走的方式都与上一次和下一次不同,根据所给的终点计算出步数最少的方案。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
#include<unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int,int>PII;
void solve(){
int x,y;
cin>>x>>y;
int ans=max(abs(x),abs(y));
if(abs(x)==abs(y)){
cout<<2*abs(x)<<'\n';
return;
}
cout<<2*ans-1<<'\n';
return;
}
int main(){
int t;
cin>>t;
while(t--) solve();
}
主要思路:本题主要考察思维,可以看出所给终点的横纵坐标绝对值可以得到坐标的较大值,假设为m,则m+1则是可以插入的其他走的方案,由于较大值产生的空隙至少m-1应该被填满,所以若两坐标值不同时,两类值加起来则是最小操作数为2*m-1。若坐标绝对值相同则横纵坐标绝对值相加则为最小操作数。
B题
题目大意:给病人打疫苗,每个人有一个来打疫苗的时间以及等待的时间,每袋疫苗里面有几管疫苗,有一定的有效时间,过了该时间就必须扔掉无法使用,现在给出每袋疫苗里面的容量,病人等待时间,以及病人数,每个病人来的时间和疫苗有效时间,计算最少需要几包疫苗。
AC代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<unordered_map>
using namespace std;
const int N=100010;
typedef long long ll;
typedef pair<int,int>PII;
void solve(){
int n,k,d,w;
cin>>n>>k>>d>>w;
vector<int>ans(n);
int res=0;
for(int i=0;i<n;i++){
cin>>ans[i];
}
int k1=w+d;
int y=ans[0]+=k1;
res++;
for(int i=0,j=0;i<n;i++){
//int y=ans[0]+k;
if(ans[i]>y||i-j+1>k){
y=ans[i]+k1;
//cout<<y<<" ";
res++;
j=i;
}
}
cout<<res<<'\n';
}
int main(){
int t;
cin>>t;
while(t--) solve();
}
主要思路:题目中所给的是升序的病人到的时间,每个人等待的时间是w,而疫苗有效时间是的,所以第一袋疫苗最晚可以打开的时间是w,最晚可以用到w+d时间,因为每袋疫苗数量有限,因此遍历时间的时候,若时间超过了最晚时间或者疫苗用完了那么久要再开一包新的。这样最终可以得到需要的最少的疫苗包数。
C题
题目大意:有一个转盘,一共有n个区域,此时指向x区域,可以给它一个范围为1-p的力,每个力可以使其转动1+2+3+...+p个区域,算出是否存在一个力使它回到原始区域。
AC代码
#include<iostream>
#include<cstring>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<vector>
typedef long long ll;
typedef std::pair<int,int>PII;
using namespace std;
const int N=100010;
void solve(){
ll n,x,p;
cin>>n>>x>>p;
p=min(2*n,p);
for(int i=1;i<=p;i++){
ll a=(((ll)(i+1)*i)/2)+x;
if(a%n==0) {cout<<"Yes"<<'\n';return;}
}
cout<<"No"<<'\n';
return;
}
int main(){
int t;
cin>>t;
while(t--) solve();
}
主要思路:首先分析出2*n为一个循环,所以2*n和p取最小值。从1开始到这个最小值进行枚举按照题目模拟即可(注意数据范围),若存在符合条件的值,则输出yes,循环结束即可,没有则输出no。