zoukankan      html  css  js  c++  java
  • [luoguP1053] 篝火晚会(贪心 + 乱搞)

    传送门

    假设第一个位置是1,那么枚举它的左右两边是谁,有两种情况,然后可以递推求出序列。

    然后可以贪心,两个序列有多少个不同的数,答案就是多少,具体为啥,yy一下即可

    然后就是判断递推求出的序列和目标序列最少有多少个不同,也就是最大有多少个相同

    因为是环,得破环为链,然后再判断的话是 n^2 的,显然超时。

    另一个思路,就是不用破环为链,随便找一个节点为起点

    看看每个位置的数到目标位置向左移的距离x,f[x]++

    如果两个数到目标位置的距离相同,那么选其中一个数到目标位置后,另一个数也能到目标位置,多个数同理

    这样我们就找最大的f[x]即可,n-f[x]为答案

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define N 60001
    
    using namespace std;
    
    int n, ans;
    int f[N], a[N], X[N], Y[N];
    
    inline int read()
    {
    	int x = 0, f = 1;
    	char ch = getchar();
    	for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
    	for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
    	return x * f;
    }
    
    inline void work()
    {
    	int i;
    	memset(a, 0, sizeof(a));
    	memset(f, 0, sizeof(f));
    	a[1] = 1, a[2] = Y[1];
    	for(i = 2; i < n; i++)
    		if(a[i - 1] != X[a[i]] && a[i - 1] != Y[a[i]])
    		{
    			puts("-1");
    			exit(0);
    		}
    		else a[i + 1] = a[i - 1] ^ X[a[i]] ^ Y[a[i]];
    	if(a[n] != X[1] || a[n - 1] ^ X[a[n]] ^ Y[a[n]] ^ a[1])
    	{
    		puts("-1");
    		exit(0);
    	}
    	for(i = 1; i <= n; i++)
    		f[((i - a[i]) % n + n) % n]++;
    	for(i = 0; i < n; i++)
    		ans = max(ans, f[i]);
    }
    
    int main()
    {
    	int i;
    	n = read();
    	for(i = 1; i <= n; i++)
    	{
    		X[i] = read();
    		Y[i] = read();
    	}
    	work();
    	swap(X[1], Y[1]);
    	work();
    	printf("%d
    ", n - ans);
    	return 0;
    }
    

      

  • 相关阅读:
    jQuery操作Table学习总结[转]
    SQL语句中的单引号处理以及模糊查询
    正则表达式实现将html文本转换为纯文本格式(将html字符串转换为纯文本方法)
    ASP.NET中使用UpdatePanel实现局部异步刷新方法和攻略(转)
    Response.Redirect在新窗口打开(转载)
    position属性absolute与relative 的区别
    下载文件
    gridveiw的使用
    MarkDown和流程图诠释你的代码
    git使用笔记
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/7677464.html
Copyright © 2011-2022 走看看