生活大爆炸版石头剪刀布
Link
模拟。
#include <bits/stdc++.h>
using namespace std;
int n,na,nb,a[2001],b[2001],ans1,ans2;
int score[5][5]={{0,0,1,1,0},{1,0,0,1,0},{0,1,0,0,1},{0,0,1,0,1},{1,1,0,0,0}};
int main()
{
cin >>n>>na>>nb;
for(int i=0;i<na;i++) cin>>a[i];
for(int i=0;i<nb;i++) cin>>b[i];
for(int i=0;i<n;i++)
{
ans1+=score[a[i%na]][b[i%nb]];
ans2+=score[b[i%nb]][a[i%na]];
}
cout<<ans1<<" "<<ans2<< endl;
return 0;
}
联合权值
Link
对于一个点,我们把它的出点放到一个vector里面,任选两个点就是距离为(2)的点对。
把每个点的出点vector遍历一遍,记录一下前缀和和前缀最大值就行了。
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
int read(){int x=0,c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))x=x*10+c-48,c=getchar();return x;}
const int N=200007,P=10007;
int max(int a,int b){return a>b? a:b;}
int inc(int a,int b){return a+=b,a>=P? a-P:a;}
int mul(int a,int b){return a*b%P;}
int n,w[N],mx,sum;vector<int>E[N],vec;
void cal(int u)
{
if(E[u].size()==1) return;
vec.clear();
for(int v:E[u]) vec.pb(w[v]);
sort(vec.begin(),vec.end());
int s=0,t=0;
for(int x:vec) sum=inc(sum,mul(x%P,s)),mx=max(mx,x*t),s=inc(x,s),t=max(t,x);
}
int main()
{
n=read();
for(int i=1,u,v;i<n;++i) u=read(),v=read(),E[u].pb(v),E[v].pb(u);
for(int i=1;i<=n;++i) w[i]=read();
for(int i=1;i<=n;++i) cal(i);
printf("%d %d",mx,inc(sum,sum));
}
飞扬的小鸟
Link
设(f_{i,j})表示坐标为((x,y))的最小点屏幕次数。
首先有(f_{i,j}=f_{i-1,j+y_i})。
然后还有(f_{i,j}=maxlimits_{kin[1,lfloorfrac j{x_i}
floor]}(f_{i-1,j-k*x_i}+k))。
然后我们发现后面这个可以变成(f_{i,j}=max(f_{i-1,j-x_i},f_{i,j-x_i})+1)。
然后就可以直接dp了。
#include<bits/stdc++.h>
using namespace std;
int read(){int x;scanf("%d",&x);return x;}
int min(int a,int b){return a<b? a:b;}
int max(int a,int b){return a>b? a:b;}
const int N=10007,M=1007,inf=0x3f3f3f3f;
int f[N][M<<1],x[N],y[N],l[N],h[N],vis[N];
int main()
{
int n=read(),m=read(),k=read(),ans=inf;memset(f,0x3f,sizeof f);
for(int i=1;i<=n;++i) x[i]=read(),y[i]=read(),h[i]=m;
for(int i=1,p;i<=k;++i) vis[p=read()]=1,l[p]=read()+1,h[p]=read()-1;
for(int i=1;i<=m;++i) f[0][i]=0;
for(int i=1,j;i<=n;++i)
{
for(j=x[i]+1;j<=m+x[i];++j) f[i][j]=min(f[i-1][j-x[i]]+1,f[i][j-x[i]]+1);
for(j=m+1;j<=m+x[i];++j) f[i][m]=min(f[i][m],f[i][j]);
for(j=1;j<=m-y[i];++j) f[i][j]=min(f[i][j],f[i-1][j+y[i]]);
for(j=1;j<l[i];++j) f[i][j]=inf;
for(j=h[i]+1;j<=m;++j) f[i][j]=inf;
}
for(int i=1;i<=m;++i) ans=min(ans,f[n][i]);
if(ans<inf) return !printf("1
%d",ans);
int i,j;
for(i=n;i;--i)
{
for(j=1;j<=m;++j){if(f[i][j]<inf)break;}
if(j<=m)break;
}
ans=0;
for(j=1;j<=i;++j) if(vis[j]) ++ans;
printf("0
%d",ans);
}
无线网络发射器选址
Link
枚举+模拟。
#include<iostream>
using namespace std;
int x,y,d,n,maxm,num,sum=1,cross[170][170];
int main()
{
cin>>d>>n;
for(int i=1;i<=n;i++) cin>>x>>y>>cross[x+20][y+20];
for(int i=20;i<=148;i++)
for(int j=20;j<=148;j++)
{
for(int m=i-d;m<=i+d;m++) for(int k=j-d;k<=j+d;k++) num+=cross[m][k];
if(maxm==num) sum++; else if(maxm<num) sum=1;
maxm=max(maxm,num),num=0;
}
cout<<sum<<" "<<maxm;
}
寻找道路
Link
先建反图找出所有能够到达终点的点。
然后找出所有符合要求的点。
再跑01最短路。
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
namespace IO
{
char ibuf[(1<<21)+1],*iS,*iT;
char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
int read(){int x=0,c=Get();while(!isdigit(c))c=Get();while(isdigit(c))x=x*10+c-48,c=Get();return x;}
}
using namespace IO;
const int N=10001,M=200007;
struct edge{int u,v;}e[M];
vector<int>E[N];int n,m,s,t,vis[N],f[N],dis[N];queue<int>q;
void dfs(int u){vis[u]=1;for(int v:E[u])if(!vis[v])dfs(v);}
int check(int u){for(int v:E[u])if(!vis[v])return 0;return 1;}
int main()
{
n=read(),m=read();
for(int i=1,u,v;i<=m;++i) u=read(),v=read(),E[v].pb(u),e[i]={u,v};
s=read(),t=read(),dfs(t);
for(int i=1;i<=n;++i) E[i].clear();
for(int i=1;i<=m;++i) E[e[i].u].pb(e[i].v);
for(int i=1;i<=n;++i) if(check(i)) f[i]=1;
if(f[s]) q.push(s);
for(int u;!q.empty();)
{
u=q.front(),q.pop();
for(int v:E[u]) if(f[v]&&!dis[v]&&v^s) dis[v]=dis[u]+1,q.push(v);
}
printf("%d",dis[t]? dis[t]:-1);
}
解方程
Link
枚举,大暴力。
注意一下高精度复杂度过高,可以采用哈希来做。
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int N=101,P=998244353;
int inc(int a,int b){return a+=b,a>=P? a-P:a;}
int mul(int a,int b){return 1ll*a*b%P;}
namespace IO
{
char ibuf[(1<<21)+1],*iS,*iT ;
char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
int read(){int x=0,f=0,c=Get();while(!isdigit(c)&&c^'-')c=Get();if(c=='-')f=1,c=Get();while(isdigit(c))x=inc(mul(x,10),c-48),c=Get();return f? inc(-x,P):x;}
}
using namespace IO;
int n,m,a[N];vector<int>ans;
int check(int x)
{
int ans=0,d=1;
for(int i=0;i<=n;++i) ans=inc(ans,mul(a[i],d)),d=mul(x,d);
return !ans;
}
int main()
{
n=read(),m=read();
for(int i=0;i<=n;++i) a[i]=read();
for(int i=1;i<=m;++i) if(check(i)) ans.pb(i);
printf("%d
",ans.size());
for(int x:ans) printf("%d
",x);
}