记一记训练录吧 - - 打的不是很好 配合还有欠缺
C. Cats
题意: 给你一个n 代表有n个猫房,每个猫房,每个猫房的高度处于1到20之间,现在要我们给出一种n个房间高度的构造,满足任意两个相等高度的猫房之间的最小值要低于此高度 ,而且相同高度的猫房不能相邻 emmmm 体会下样例吧 (虽然样例很水)
那么我们要做的是对于任意相等的高度 中间的最小值不能大于等于这个高度 ,那么顿生一悟,如果按照1–20轮流插入,比如先安排1,1的两边安排2,每个2的两边安排3,同理 下去 ,会发现这种构造是很妙也很满足式子的,那么顶多构造2^0 一直 到2^19 必然满足题意的n 然后就开始模拟上述过程,两个队列模拟就完事 。
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<algorithm>
#include<deque>
#include<map>
#include<stdlib.h>
#include<set>
#include<iomanip>
#include<stack>
#define ll long long
#define ms(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x & -x
#define fi first
#define ull unsigned long long
#define se second
#define lson (rt<<1)
#define rson (rt<<1|1)
#define endl "\n"
#define bug cout<<"----acac----"<<endl
#define IOS ios::sync_with_stdio(false), cin.tie(0),cout.tie(0)
using namespace std;
const int maxn = 4e5 + 10;
const int maxm = 1e4 + 50;
const double eps = 1e-7;
const ll inf = 0x3f3f3f3f;
const ll lnf = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
int main()
{
int n;
scanf("%d",&n);
int xx=1;
int res=0;
for(int i=1;i<=20;i++)
{
xx*=2;
if(xx<=n)res++;
}
res++;
queue<int>a,b;
a.push(1);
int rt=0;
for(int i=2;i<=res;i++)
{
if(rt==0)
{
b.push(i);
while(!a.empty())
{
int tem=a.front();
b.push(tem);
a.pop();
b.push(i);
}
}else
{
a.push(i);
while(!b.empty())
{
int tem=b.front();
a.push(tem);
b.pop();
a.push(i);
}
}
rt^=1;
}
for(int i=1;i<=n;i++)
{
if(rt==1)
{
printf("%d ",b.front());
b.pop();
}else
{
printf("%d ",a.front());
a.pop();
}
}
return 0;
}
D题 Delete Prime
题意:对于一个序列 1–n 我们有一种拿取规则 构造出数组D【】
每次拿走第一个数和 下标为质数的数依次放入D数组中,然后原序列重新排列也就是接上去被拿的地方,然后重新依照上述规则取值放入D数组,直到被拿完,现在有T组询问,每次有两种操作中的一种,给出n,k
操作1询问在D数组中满足D[X]等于k 的X 是多少
操作2询问在D数组中第K个数是多少 (n,k范围1e6)
不难发现不论n多大,数字在第几轮操作中被拿取是固定的,那么我们先预处理一个表,表示第i轮拿走的第p个数是num ,然后对于上述询问,直接枚举轮数,二分查找就OK
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<algorithm>
#include<deque>
#include<map>
#include<stdlib.h>
#include<set>
#include<iomanip>
#include<stack>
#define ll long long
#define ms(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x & -x
#define fi first
#define ull unsigned long long
#define se second
#define lson (rt<<1)
#define rson (rt<<1|1)
#define endl "\n"
#define bug cout<<"----acac----"<<endl
#define IOS ios::sync_with_stdio(false), cin.tie(0),cout.tie(0)
using namespace std;
const int maxn = 1e6 + 10;
const int maxm = 1e4 + 50;
const double eps = 1e-7;
const ll inf = 0x3f3f3f3f;
const ll lnf = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
vector<int>v,ans;
int spr[maxn],cnt=0,vis[maxn];
void ol()//筛选素数,一定要记住素数的最大范围vis[i]=1代表是素数
{
ms(vis, 1);
vis[0] = vis[1] = 0;
for (int i = 2; i < maxn; i++)
{
//q.push(i);
if (vis[i])spr[cnt++] = i;
for (ll j = 0; i * spr[j] < maxn && j < cnt; j++)
{
vis[i * spr[j]] = 0;
if (i % spr[j] == 0)break;
}
}
}
vector<int>vec[200];
queue<int>q,p;
map<int,int>mp;
int main()
{
ol();
//printf("size %d\n",q.size());
for(int i=1; i<=1000000; i++)q.push(i);
int rt=0;
int cnt=0;
int cen=1;
while(1)
{
if(q.size()==0&&p.size()==0)break;
cnt++;
if(rt==0)
{
int tem=q.front();
q.pop();
if(cnt==1||vis[cnt])
{
// printf("Q%d %d\n",cnt,cen);
vec[cen].push_back(tem);
mp[tem]=cen;
}
else
{
p.push(tem);
}
if(q.size()==0)
{
rt=1;
cen++;
cnt=0;
}
}
else
{
int tem=p.front();
p.pop();
if(cnt==1||vis[cnt])
{
//printf("W%d %d\n",cnt,cen);
vec[cen].push_back(tem);
mp[tem]=cen;
}
else
{
q.push(tem);
}
if(p.size()==0)
{
rt=0;
cen++;
cnt=0;
}
}
}
int t;
scanf("%d",&t);
while(t--)
{
int op;
int n;
int k;
scanf("%d%d%d",&op,&n,&k);
if(op==1)
{
int ans=0;
for(int i=1; i<=cen; i++)
{
int pos=lower_bound(vec[i].begin(),vec[i].end(),k)-vec[i].begin();
int pos_s=pos+1;
if(vec[i][pos]!=k)
{
int pp=lower_bound(vec[i].begin(),vec[i].end(),n)-vec[i].begin();
int pp_s=pp+1;
// ans=ans+pos-1;
if(vec[i][pp]!=n)
{
ans=ans+(pp_s-1);
}
else
{
ans=ans+pp_s;
}
continue;
}
else
{
ans=ans+pos_s;
break;
}
}
printf("%d\n",ans);
continue;
}
else
{
int ans=0;
// k--;
// int befor;
for(int i=1; i<=cen; i++)
{
// befor=ans;
int pos=lower_bound(vec[i].begin(),vec[i].end(),n)-vec[i].begin();
int pos_s=pos+1;
int rnm;
if(vec[i][pos]!=n)
{
// k=k-(pos-1);
rnm=pos_s-1;
}
else
{
// k=k-pos;
rnm=pos_s;
}
if(k<=rnm)
{
//k=k+rnm;
printf("%d\n",vec[i][k-1]);
break;
}
else
{
k=k-rnm;
}
}
}
}
}
J题 Just Multiplicative Inverse
题意就是 质数p 然后还有一个F(x,p) 递归函数
x的取值范围是1到p-1 现在要我们求给定n p 的期望
其实不难发现 根据样例,每个F(x,p)的贡献就是它可以执行的递归的轮数,最终只需要把1到p-1 的总轮数求和 除p-1 就是答案,由于p是1e6的范围,递归F(x,p) 直接搞会超时,加个记忆化就OK
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<algorithm>
#include<deque>
#include<map>
#include<stdlib.h>
#include<set>
#include<iomanip>
#include<stack>
#define ll long long
#define ms(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x & -x
#define fi first
#define ull unsigned long long
#define se second
#define lson (rt<<1)
#define rson (rt<<1|1)
#define endl "\n"
#define bug cout<<"----acac----"<<endl
#define IOS ios::sync_with_stdio(false), cin.tie(0),cout.tie(0)
using namespace std;
const int maxn = 1e6 + 10;
const int maxm = 1e4 + 50;
const double eps = 1e-7;
const ll inf = 0x3f3f3f3f;
const ll lnf = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
int res=0;
int dp[101][maxn];
int f(int x,int p,int num)
{
if(dp[num][x])return res=res+dp[num][x];
res++;
if(x<=1)
return dp[num][x]=res;
// else
return dp[num][x]=f(p%x,p,num);
// return -(p/x)*%p;
}
int main()
{ int t;
scanf("%d",&t);
while(t--){
int p;
scanf("%d",&p);
int sum=0;
int ans=0;
int ma=0;
for(int i=1;i<=p-1;i++)
{
res=0;
sum+=f(i,p,t);
}
printf("%.10lf\n",sum*1.0/(p-1));
}
}
G Grid Coloring
题意 给我们一个n*m的矩阵,定义相邻三个块颜色相同则该图形是不好的
现在给我们n ,m 求好的方案数并且%mod 基操
没啥好讲的,这种必然是规律题,不妨写个暴力代码打表观察下
(默认大家都打出表了)
显然显然显然以后我们特判把情况筛掉了后,只剩下n=1,2,3 范围下的数据,然后又可以打表显然的发现是成斐波那契数列分布,那就很显然了,1e9,直接上矩阵快速幂 ,完事
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int mod = 1e9+7;
int N;
ll base[10][10],ans[10][10],t[10][10];
void timea()
{
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
t[i][j]=ans[i][j],ans[i][j]=0;
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
for(int k=1;k<=N;k++)
ans[i][j]=(ans[i][j]+(t[i][k]*base[k][j]%mod))%mod;
}
void timeb()
{
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
t[i][j]=base[i][j],base[i][j]=0;
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
for(int k=1;k<=N;k++)
base[i][j]=(base[i][j]+(t[k][j]*t[i][k]%mod))%mod;
}
void qpow(ll b)
{
while(b)
{
if(b&1)
timea();
timeb();
b>>=1;
}
}
int T;
ll n,m;
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
if(n>m) swap(n,m);
if(n>=5) puts("8");
else if(n==4)
{
if(m==4)
puts("18");
else puts("14");
}
else if(n==1)
{
N=2;
base[1][1]=ans[1][1]=1;
base[1][2]=ans[1][2]=1;
base[2][1]=ans[2][1]=1;
base[2][2]=ans[2][2]=0;
qpow(m-1);
printf("%lld\n",(2*ans[1][1])%mod);
}
else if(n==2)
{
N=2;
base[1][1]=ans[1][1]=1;
base[1][2]=ans[1][2]=1;
base[2][1]=ans[2][1]=1;
base[2][2]=ans[2][2]=0;
qpow(m-1);
ll ret=(2*ans[1][1])%mod;
printf("%lld\n",(ret*ret)%mod); // 1 2 3 5 8
}
else if(n==3)
{
if(m==3){
puts("32");
continue;
}
else if(m==4)
{
puts("44");
continue;
}
else if(m==5)
{
puts("64");
continue;
}
N=2;
base[1][1]=ans[1][1]=1;
base[1][2]=ans[1][2]=1;
base[2][1]=ans[2][1]=1;
base[2][2]=ans[2][2]=0;
qpow(m-6);
ll ret=ans[1][1]*60+ans[1][2]*40;
printf("%lld\n",(ret+4)%mod);
}
}
return 0;
}
//2 4 6 10 16
// 4
H Happy Morse Code
题意: 给了我们n个长度不超过5的字符串,格式为 字母-01字符串
再给我们一个母串,现在询问可以由上述n个字符串组合成母串并且各不相同的方案数,无解就输出xxxxx 按题意搞吧,有解还要判断有多少个解 xxxxx
线性dp 听队友是这么搞的 emmmmm
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
#define pb(x) push_back(x)
using namespace std;
const int maxn = 1e5 + 10;
const int maxm = 1e4 + 50;
const ll inf = 0x3f3f3f3f;
const ll lnf = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
map<string,int>mp;
string str;
string b[30];
int dp[maxn],fl[maxn],one[maxn];
int main()
{
int _;
cin>>_;
while(_--)
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)dp[i]=one[i]=fl[i]=0;
for(int i=1;i<=m;i++)
{
string a;
cin>>a>>b[i];
}
cin>>str;
dp[0]=1,fl[0]=1,one[0]=1;
for(int i=0;i<n;i++)
{
//dp[i]=dp[i-1];
for(int j=1;j<=m;j++)
{
if(b[j].size()+i>n)continue;
if(str.substr(i,b[j].size())==b[j])
{
//print1;
dp[i+b[j].size()]+=dp[i];
dp[i+b[j].size()]%=128;
fl[i+b[j].size()]+=fl[i];
}
fl[i+b[j].size()]=min(10,fl[i+b[j].size()]);
}
}
//for(int i=0;i<=n;i++)
// cout<<dp[i]<<" ";
//cout<< str.substr(0,2)<<" ";
if(fl[n]==0)
{
cout<<"nonono"<<endl;
}else
{
if(fl[n]==1)
cout<<"happymorsecode"<<endl;
else
cout<<"puppymousecat "<<dp[n]%128<<endl;
}
}
}
或许能在江苏苟到一块银牌?