CCPC-Wannafly Winter Camp Day7 Div2

今天外婆生日,比赛没打完,只有3个题就滚粗了。

A.迷宫

这句话的意思是一个节点不能同时存在两个人

我们这样分析一下,是不是最终所有点都要到1节点,那我们只要求出所有人到1号点的距离d[i],排个序,假设ans为所有人全部逃跑花费的时间(初始0),遍历到第 i 个点,如果d[ i ]>ans,那么就更新ans=d[ i ],如果d[ i ]<=ans,是不是这个人要排队?此时更新ans=ans+1

#include
using namespace std;
const int maxn=1e5+10;
vectorG[maxn];
int a[maxn],d[maxn],cnt,ans;
int dfs(int u,int fa,int deep)
{
	if(a[u])d[++cnt]=deep;
	for(int i=0;ians)ans=d[i];
	else ans++;
	cout<

E.线性探查法

假设a[ 2 ]%7=5,a[ 2 ]本应该在第5个位置,但是却排到了第 2 位,说明已经有的数先抢占了5 6 0 1这些位置,那么连四条有向边到 2 即可,我们通过这种方式建有向图进行拓扑排序,不过普通队列换成权值小的数优先的优先队列就好了。

#include
#define ll long long
using namespace std;
const int maxn=100005;
int n,d[maxn];
ll a[maxn],b[maxn];
vectorG[maxn];
struct node
{
	ll x;
	int id;
	node(ll t1,int t2)
	{
		x=t1,id=t2;
	}
	bool operator<(const node& t)const
	{
		return x>t.x;
	}
};
priority_queueq;
void toposort()
{
	for(int i=0;i>n;
	for(int i=0;i>b[i];
		if(b[i]%n!=i)
		for(int j=b[i]%n;;j++)
		{
			int k=j%n;
			if(k==i)break;
			G[k].push_back(i);
			d[i]++;
		}
	}
	toposort();
	for(int i=1;i

F.逆序对!

我们枚举a[ i ]和a[ j ](j>i),然后进行数位dp算逆序贡献,先把m换成二进制,从高位到低位枚举,假设a[ i ]为 101xx,a[ j ]为100xx,a[ i ]和a[ j ]从高位枚举在第3位开始不同, 假设m当前枚举到了2位(即二进制10),我们发现所有的x<=10,同时异或a[ i ],a[ j ],a[ i ]>a[ j ],那么对答案的贡献就是2^1,假设m当前枚举到得到是第3位(即100),我们只有只有100异或他们才会不造成贡献,因此此时对答案的贡献是2^2-1,假设m枚举的是第4位,我们不难发现2^3只有一半的数才会对答案造成贡献,我只分析一半,剩下给大家了。

#include
#define ll long long
using namespace std;
const int maxn=1005,mod=998244353;
int b[maxn],a[35],cnt;
ll ans;
void add(ll& x,ll y)
{
	x=(x+y)%mod;
}
int dfs(int x,int y,int k)
{
	if(!k)return 0;
	if(!a[k])return dfs(x,y,k-1);
	int tp=0,p;
	for(int i=29;i>=0;i--)
	{
		int t1=0,t2=0;
		if(x&(1<k)res=all;
	else if(p==k)res=all-1;
	else res=all/2;
	if(!tp)res=all-res;
	return res+dfs(x^(1<>n>>m;
	for(int i=1;i<=n;i++)
	cin>>b[i];
	while(m)
	{
		a[++cnt]=m%2;
		m/=2;
	}
	for(int i=1;i

G.抢红包机器人

update:最近一个月已经被人hacked起码有5次了(我枯了),已被hacked,谢谢网友的指出,数据 5 3 5 1 2 3 4 5 3 3 2 1 2 5 4,推荐一个暴力解法: wzazzy

阅读理解题,机器人a可能在b前面,也可能在b的后面,是不是有点像强连通定义?那就对了,我们按照顺序连接ai-->ai+1建立有向图,求强连通,最小的强连通分量的大小就是答案。

#include
using namespace std;
const int maxn=105;
vectorG[maxn];
int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt,vis[maxn];
stackS;
void dfs(int u)
{
	pre[u]=lowlink[u]=++dfs_clock;
	S.push(u);
	for(int i=0;i>n>>m;
	for(int i=1;i<=m;i++)
	{
		cin>>k;
		for(int j=1;j<=k;j++)cin>>a[j];
		for(int j=1;j

J.强壮的排列

待补

 

 

你可能感兴趣的:(比赛----其他比赛题解)