牛客白月赛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题解

牛客白月赛8题解

牛客白月赛28题解

牛客白月赛28题解

牛客白月赛4 题解

牛客白月赛11题解