1.Primality Test
题意:f(x)代表大于x的第一个质数,求g(x)=[(f(x)+f(f(x)))/2],就是求大于x的下一个质数和下下一个质数加起来除2,问g(x)是否为质数
思路:枚举了几个x,发现除了当x=1,g(x)为质数,否则当x>1时,g(x)为偶数,不可能为质数
核心代码
if(x==1)
{
cout<<"YES"<<endl;
}
else
{
cout<<"NO"<<endl;
}
2.Kanade Doesn’t Want to Learn CG
题意:给你一个抛物线投篮,问能不能进,撞到篮板水平速度变向,竖直速度不变
思路:两种情况进球(1)直接进球(2)打到篮板反弹进球
核心代码
#include<iostream>
#include<algorithm>
using namespace std;
double a, b, c, x0, x1, z0, z1, z2;
double fun(double x)
{
return a * x * x + b * x + c;
}
int main()
{
int t;
cin >> t;
while (t--) {
cin >> a >> b >> c;
cin >> x0 >> x1 >> z0 >> z1 >> z2;
double yy0 = fun(x0);
double yy1 = fun(x1);
double dyy0 = fun(x0 + 2 * (x1 - x0));
if (yy0 > z0 && yy1 <= z2 && yy1 > z0)
{
if (dyy0 < z0)
{
cout << "Yes" << endl;
}
else
{
cout << "No" << endl;
}
}
else if (yy0 > z0 && yy1 < z0)
{
cout << "Yes" << endl;
}
else
{
cout << "No" << endl;
}
}
}
3.Nun Heh Heh Aaaaaaaaaaa
思路:统计号前缀数量,一旦统计好nunhehheh,和后面统计好的a的数量进行排列组合,要用快速幂,快速乘
核心代码
for(int i=0; i<len; i++)
{
if(s[i]=='n')
{
num[3]+=num[2]%mod;
num[1]++;
}
else if(s[i]=='u')
{
num[2]+=num[1]%mod;
}
else if(s[i]=='h')
{
num[7]+=num[6]%mod;
num[6]+=num[5]%mod;
num[4]+=num[3]%mod;
num[9]=(num[9]+ksmc(num[8],(ksm(2,a[i+1])-1))%mod)%mod; }
else if (s[i]=='e')
{
num[8]+=num[7]%mod;
num[5]+=num[4]%mod;
}
}
4.Monopoly
题意:玩大富翁,给你一个地图,首尾相连,只能一步一步走,每个地方都有权值x,如果该地方权值为正,则分数增加x,否则分数减少x,问如果要达到y分最少要走几步,如果达不到这个分数输出-1,能达到输出最少要走的步数
思路:设S为每一步的得分序列,要找到最小的i使S[i]=y;设地图走一圈的收益为sum
(1)sum>0
s[i]=s[j]+k*sum,(1<=j<=n,k>=0),如果s[j]越大,k越小,步数越少,且s[i]和s[j]模sum同余,所以我们要在与y模sum同余的数中找到小于等于y的最大整数,
(2)sum<0
把序列翻转过来,将需求反过来,同(1)处理
(3)sum==0
sum等于0就只要在(1~n)的s序列中找就行了,因为多走个循环没有收益
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int maxn = 2e5+5;
ll a[maxn],p[maxn];
ll n,m,s;
map <ll,ll> vis;//用于当原数组前缀和为0
map <ll,vector<pll>> mp;//第一个数代表取模后的余数,pll的第一个代表可以减循环的数,第二个是位置
void solve()
{
bool flag=0;
cin>>n>>m;
s=0;
for(int i=1; i<=n; i++)
{
cin>>a[i];
p[i]=p[i-1]+a[i];
s+=a[i];
}
if(s<0)
{
flag=1;
s=-s;
for(int i=1;i<=n;i++)
{
p[i]=-p[i];
}
}
if(s==0)
{
vis.clear();
for(int i=1; i<=n; i++)
{
if(vis.find(p[i])==vis.end())//如果在vis没存过才存,因为答案要取最前面的
{
vis[p[i]]=i;
}
}
while(m--)
{
ll x;
cin>>x;
if(x==0)
{
cout<<0<<endl;
continue;
}
if(vis.find(x)==vis.end())
{
cout<<-1<<endl;
}
else
{
cout<<vis[x]<<endl;
}
}
return ;
}
mp.clear();
for(int i=1;i<=n;i++)
{
ll ys=(p[i]%s+s)%s;//保持余数为正数,要做索引
mp[ys].push_back({-p[i],i});
}
for(auto it=mp.begin();it!=mp.end();it++)
{
sort(it->second.begin(),it->second.end());//it代表的是一个pair,it->first是key,it->second是value
}
while(m--)
{
ll x;
cin>>x;
if(x==0)
{
cout<<0<<endl;
continue;
}
if(flag)x=-x;
ll xys=(x%s+s)%s;
if(mp.find(xys)==mp.end())
{
cout<<-1<<endl;//没找到
continue;
}
pll as={-x,0};
ll sum=lower_bound(begin(mp[xys]),end(mp[xys]),as)-mp[xys].begin();
if(sum==mp[xys].size())
{
cout<<-1<<endl;
}
else
{
ll ans=mp[xys][sum].second;//相当于找到的s[j]
ans+=(x+mp[xys][sum].first)/s*n;///抵消多余的圈数
cout<<ans<<endl;
}
}
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--)
{
solve();
}
}