牛客白月赛2 题解
Posted 辉小歌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客白月赛2 题解相关的知识,希望对你有一定的参考价值。
https://ac.nowcoder.com/acm/contest/86
目录
数字方阵【构造】
构造题,不咋会,难想。
#include<bits/stdc++.h>
using namespace std;
int n,a[1010][1010];
int main(void)
cin>>n;
int step=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n-1;j++) a[i][j]=step++;
for(int i=1;i<=n;i++) a[i][n]=step++;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) cout<<a[i][j]<<" ";
cout<<endl;
return 0;
rand()做法,很玄学,结果在80%-96%
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,a[1010][1010],st[N];
int main(void)
cin>>n;
srand(time(0));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
int t=rand()%(n*n)+1;
while(st[t])
t=rand()%(n*n)+1;
a[i][j]=t;
st[t]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) cout<<a[i][j]<<" ";
cout<<endl;
return 0;
小马过河【计算几何】
通过u,v俩点可以确定该线的方程。然后因为垂直,故俩线的斜率乘积为-1。故k1*k2==-1
解这个方程即可,这是一个一元一次的方程。
#include<bits/stdc++.h>
using namespace std;
double x00,y00,x11,y11,x22,y22;
int main(void)
int t; cin>>t;
while(t--)
cin>>x00>>y00>>x11>>y11>>x22>>y22;
double k=(y22-y11)/(x22-x11);
double b=y22-k*x22;
double x=(x00+y00*k-b*k)/(k*k+1);
double y=k*x+b;
printf("%.6lf %.6lf\\n",x,y);
return 0;
真真假假【打表】
#include<bits/stdc++.h>
using namespace std;
string s[40]=
"algorithm","bitset","cctype","cerrno", "clocale",
"cmath","complex","cstdio","cstdlib","cstring",
"ctime","deque","exception","fstream","functional",
"limits","list","map","iomanip","ios",
"iosfwd","iostream","istream","ostream","queue",
"set","sstream","stack","stdexcept","streambuf",
"string","utility","vector","cwchar","cwctype"
;
int main(void)
int t; cin>>t;
while(t--)
string a; cin>>a;
bool flag=0;
for(int i=0;i<35;i++) if(s[i]==a) flag=1;
if(flag) puts("Qian");
else puts("Kun");
return 0;
虚虚实实【欧拉路径判断】
无向图判断,是不是欧拉路径。度为奇数的点的个数为0或2。且该图是联通的。
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int p[N],d[N],t,n,m;
int find(int x)
if(x!=p[x]) p[x]=find(p[x]);
return p[x];
int main(void)
cin>>t;
while(t--)
cin>>n>>m;
for(int i=1;i<=n;i++) p[i]=i,d[i]=0;
map<int,int>mp;//统计连通块的数目
while(m--)
int a,b; cin>>a>>b;
d[a]++,d[b]++;
p[find(a)]=find(b);
int cnt=0;
for(int i=1;i<=n;i++)
if(d[i]&1) cnt++;
mp[find(i)]++;
if((cnt==0||cnt==2)&&mp.size()==1) puts("Zhen");
else puts("Xun");
return 0;
是是非非【Nim博弈】
Nim游戏的经典模型,将所有的数异或结果不为0则必胜,否则则不是。
这里有多次的查询,需要一直维护总的异或值。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef long long int LL;
LL a[N],sum,n,m;
int main(void)
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i],sum^=a[i];
while(m--)
LL x,y; cin>>x>>y;
sum=sum^a[x]^y;
a[x]=y;
if(sum) puts("Kan");
else puts("Li");
return 0;
黑黑白白【树上博弈】
如果我走了一步,使得下一步都是必输的,则对方处于“必败”境地,那么我就处于“必胜”境地。
如果我的所有下一步状态都是“必败”态,那么我就一定会输。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
vector<int>ve[N];
int t,n,root;
bool dfs(int u,int fa)
for(int i=0;i<ve[u].size();i++)
int j=ve[u][i];
if(j==fa) continue;
if(!dfs(j,u)) return 1;//我的下一步是必败状态,则我是必胜的。
return 0;
int main(void)
cin>>t;
while(t--)
cin>>n>>root;
for(int i=1;i<=n;i++) ve[i].clear();
for(int i=1;i<=n-1;i++)
int a,b; cin>>a>>b;
ve[a].push_back(b);
ve[b].push_back(a);
if(dfs(root,-1)) puts("Gen");
else puts("Dui");
return 0;
文【排序】
#include<bits/stdc++.h>
using namespace std;
int n,m;
struct node
string name;
double score;
;
bool cmp(node a,node b)
if(a.score==b.score) return a.name<b.name;
return a.score>b.score;
vector<node>ve;
string ans;
int main(void)
cin>>n>>m;
cin>>ans;
while(m--)
string a,b; cin>>a>>b;
int cnt=0;
for(int i=0;i<b.size();i++) if(b[i]==ans[i]) cnt++;
ve.push_back(a,(100.0*cnt)/n);
sort(ve.begin(),ve.end(),cmp);
cout<<ve[0].name<<endl;
printf("%.2lf",ve[0].score);
return 0;
武【最短路】
跑一下Dijkstra,输出第k小的就行。
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=1e5*2+10;
int h[N],e[N],w[N],ne[N],idx;
int n,m,p,dist[N],st[N];
void add(int a,int b,int c)
e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
void Dijkstra(int u)
memset(dist,0x3f,sizeof dist);
dist[u]=0;
priority_queue<PII,vector<PII>,greater<PII>>q; q.push(0,u);
while(q.size())
auto temp=q.top(); q.pop();
u=temp.second;
if(st[u]) continue;
st[u]=1;
for(int i=h[u];i!=-1;i=ne[i])
int j=e[i];
if(dist[j]>dist[u]+w[i])
dist[j]=dist[u]+w[i];
q.push(dist[j],j);
int main(void)
memset(h,-1,sizeof h);
cin>>n>>m>>p;
for(int i=1;i<=n-1;i++)
int a,b,c; cin>>a>>b>>c;
add(a,b,c),add(b,a,c);
Dijkstra(m);
vector<int>ve;
for(int i=1;i<=n;i++)
if(i!=m) ve.push_back(dist[i]);
sort(ve.begin(),ve.end());
cout<<ve[p-1];
return 0;
艺【贪心】
贪心,注意对于每个时刻,取A和B或者不选,因为有负的值。
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
typedef pair<int,int> PII;
vector<PII>a,b;
int n,m,t;
int main(void)
cin>>n>>m>>t;
for(int i=0;i<n;i++)
int l,r; cin>>l>>r;
a.push_back(牛客白月赛25题解