zoukankan      html  css  js  c++  java
  • [Codeforces] 592 div2 A B D E

    A - Pens and Pencils

     emm题意忘了

    B - Rooms and Staircases

     有两层房子,每层有k间 每间要么是0要么是1 0只能左右, 1可以上下 问最多能走多少间。

    不用考虑上下左右来回走,枚举每个转折上面走最大下面走最大更新极值即可,来回走必然不如这样优

    /*
        Zeolim - An AC a day keeps the bug away
    */
      
    //#pragma GCC optimize(2)
    //#pragma GCC ("-W1,--stack=128000000")
    #include <bits/stdc++.h>
    using namespace std;
    #define mp(x, y) make_pair(x, y)
    #define fr(x, y, z) for(int x = y; x < z; ++x)
    #define pb(x) push_back(x)
    #define mem(x, y) memset(x, y, sizeof(x))
    typedef long long ll;
    typedef unsigned long long ull;
    typedef long double ld;
    typedef std::pair <int, int> pii;
    typedef std::vector <int> vi;
    //typedef __int128 ill;
    const ld PI = acos(-1.0);
    const ld E = exp(1.0);
    const ll INF = 0x3f3f3f3f;
    const ll MOD = 1e9 + 7;
    const ull P = 13331;
    const int MAXN = 2e6 + 10;
     
    int dp[MAXN][2] = {0};
     
    int main()
    { 
    	ios::sync_with_stdio(0);
    	cin.tie(0); cout.tie(0);
    	//freopen("1.txt", "r", stdin);
     
    	int T;
    	
    	cin >> T;
    	
    	while(T--)
    	{
    		int n;
    		cin >> n;
    		int ans = 0;
    		string s;
    		cin >> s;
    		if(s.find('1') == string::npos)
    			cout << n << '
    ';
    			
    		else
    		{
    			int cnt = 0;
    			int fst = INF;
    			int lst = -INF;
    			for(int i = 0; i < n; ++i)
    			{
    				if(s[i] == '1')
    				{
    					++cnt;
    					fst = min(fst, i);
    					lst = max(lst, i);
    				}
    			}
    			
    			++fst, ++lst;
    			int ans = 0;
    			
    			ans = max(ans, n - fst + 1);
    			ans = max(ans, fst);
    			ans = max(ans, n - lst + 1);
    			ans = max(ans, lst);
    			
    			cout << ans * 2 << '
    ';
    		}
    		
    	}
        
        return 0;
    }
    D - Paint the Tree

    给定一颗树,相邻三个节点颜色不能涂一样,每个节点可以涂三个颜色,不同颜色的权值给定

    首先发现,树深度大于2必然有矛盾,所以这个树就是链,然后在链上dp就行

    其实不用dp 直接枚举开始两个节点的情况暴力跑6遍就行 因为限定前两个以后后面情况是唯一的

    /*
        Zeolim - An AC a day keeps the bug away
    */
      
    //#pragma GCC optimize(2)
    //#pragma GCC ("-W1,--stack=128000000")
    #include <bits/stdc++.h>
    using namespace std;
    #define mp(x, y) make_pair(x, y)
    #define fr(x, y, z) for(int x = y; x < z; ++x)
    #define pb(x) push_back(x)
    #define mem(x, y) memset(x, y, sizeof(x))
    typedef long long ll;
    typedef unsigned long long ull;
    typedef long double ld;
    typedef std::pair <int, int> pii;
    typedef std::vector <int> vi;
    //typedef __int128 ill;
    const ld PI = acos(-1.0);
    const ld E = exp(1.0);
    const ll INF = 0x3f3f3f3f3f3f3f;
    const ll MOD = 1e9 + 7;
    const ull P = 13331;
    const int MAXN = 1e6 + 10;
     
    vector <int> edge[MAXN];
    ll v[MAXN][3];
     
    vector <int> ans, t;
     
    ll rs = 0, rans = INF;
     
    bitset <MAXN> used;
     
    void dfs(int now, int fa, int lfa)
    {
    	used[now] = 1;
    	for(int i = 0; i < 3; ++i)
    	{
    		if(i != t[fa] && i != t[lfa])
    		{
    			t[now] = i;
    			rs += v[now][i];
    		}	
    	}
    	for(auto to : edge[now])
    	{
    		if(!used[to])
    			dfs(to, now, fa);
    	}
    }
     
    void gao(int beg, int x, int y)
    {
    	used.reset();
    	rs = 0;
        t[beg] = x;
        int bto = edge[beg][0];
        t[bto] = y;
        rs = v[beg][x] + v[bto][y];
        used[beg] = 1;
        used[bto] = 1;
        for(auto to : edge[bto])
        {
        	if(!used[to])
        	{
        		dfs(to, bto, beg);
    		}
    	}
    	if(rs < rans)
    	{
    		rans = rs;
    		ans = t;
    	}
    }
     
    int main()
    { 
    	ios::sync_with_stdio(0);
    	cin.tie(0); cout.tie(0);
    	//freopen("1.txt", "r", stdin);
     
    	int n;
    	
    	cin >> n;
    	
    	for(int i = 1; i <= n; ++i)
    		cin >> v[i][0];
    	
    	for(int i = 1; i <= n; ++i)
    		cin >> v[i][1];
    		
    	for(int i = 1; i <= n; ++i)
    		cin >> v[i][2];
    		
    	for(int i = 1; i < n; ++i)
    	{
    		int x, y;
    		cin >> x >> y;
    		edge[x].pb(y);
    		edge[y].pb(x);
    	}
    	
    	int beg = 0;
    	for(int i = 1; i <= n; ++i)
    	{
    		if(edge[i].size() > 2)
    		{
    			cout << "-1
    ";
    			return 0;
    		}
    		if(edge[i].size() == 1)
    			beg = i;
    	}
     
        ans.resize(n + 1);
        t.resize(n + 1);
        
        gao(beg, 0, 1);
        gao(beg, 1, 0);
        gao(beg, 1, 2);
        gao(beg, 2, 1);
        gao(beg, 0, 2);
        gao(beg, 2, 0);
        
        cout << rans << '
    ';
        
        for(int i = 1; i <= n; ++i)
        	cout << ans[i] + 1 << ' ';
        
        return 0;
    }
    E - Minimizing Difference

    题意:给定一个序列和一个k,你可以操作至多k次,每次操作可以将任意一个数字加1也可以将任意一个数字减1 

    求操作后序列最大值减最小值差值最小;

    思路:首先考虑将数组中个某个值当作上界或下界,再分别二分查找以当前值为上界/下界所能达到的最优值,更新答案即可

    对于每次check,小于左边界的所有值必须要加左边界,大于二分右边界的都要减到右边界,可以在序列中二分位置+前缀和快速计算

    复杂度O(nloglogn)

    /*
        Zeolim - An AC a day keeps the bug away
    */
     
    //#pragma GCC optimize(2)
    //#pragma GCC ("-W1,--stack=128000000")
    #include <bits/stdc++.h>
    using namespace std;
    #define mp(x, y) make_pair(x, y)
    #define fr(x, y, z) for(int x = y; x < z; ++x)
    #define pb(x) push_back(x)
    #define mem(x, y) memset(x, y, sizeof(x))
    typedef long long ll;
    typedef unsigned long long ull;
    typedef long double ld;
    typedef std::pair <int, int> pii;
    typedef std::vector <int> vi;
    //typedef __int128 ill;
    const ld PI = acos(-1.0);
    const ld E = exp(1.0);
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const ll MOD = 386910137;
    const ull P = 13331; 
    const int MAXN = 1e6 + 10;
     
    ll n, k;
    ll arr[MAXN] = {0}, pre[MAXN] = {0}, rpre[MAXN] = {0};
    ll rk;
    bool check(ll val)
    {
    	int pos = lower_bound(arr, arr + n, val) - arr;
    	ll rx = rpre[pos] - val * (n - pos);
    	return rx <= rk;
    }
    bool check1(ll val)
    {
    	if(arr[0] >= val)
    		return 1;
    	int pos = lower_bound(arr, arr + n, val) - arr;
    	while(arr[pos] >= val) --pos;
    	ll rx = val * (pos + 1) - pre[pos];
    	return rx <= rk;
    }
     
    int main()
    {  
        ios::sync_with_stdio(0);
        cin.tie(0); cout.tie(0);
        //freopen("d:out.txt","w",stdout);
        //freopen("d:in.txt","r",stdin);
        
        cin >> n >> k;
        
        for(ll i = 0; i < n; ++i)
        	cin >> arr[i];
        	
       	sort(arr, arr + n);
       	
       	pre[0] = arr[0];
       	
    	for(ll i = 1; i < n; ++i)
    		pre[i] = pre[i - 1] + arr[i];
    	
    	rpre[n - 1] = arr[n - 1];
    	
    	for(ll i = n - 2; i >= 0; --i)
    		rpre[i] = rpre[i + 1] + arr[i];
    		
    	ll ans = INF;
    	
    	for(ll i = 0; i < n; ++i)
    	{
    		ll rval = arr[i] * (i + 1);
    		ll rx = rval - pre[i];
    		if(rx > k) break;
    		rk = k - rx;
    		ll fst = arr[i], lst = arr[n - 1], mid;
    		while(fst <= lst)
    		{
    			mid = (fst + lst) / 2;
    			if(check(mid))
    			{
    				ans = min(ans, mid - arr[i]);
    				lst = mid - 1;
    			}
    			else
    			{
    				fst = mid + 1;
    			}
    		}
    	}
    	
    	for(ll i = n - 1; i >= 0; --i)
    	{
    		ll rval = arr[i] * (n - i);
    		ll rx = rpre[i] - rval;
    		if(rx > k) break;
    		rk = k - rx;
    		ll fst = 0, lst = arr[i], mid;
    		while(fst <= lst)
    		{
    			mid = (fst + lst) / 2;
    			if(check1(mid))
    			{
    				ans = min(ans, arr[i] - mid);
    				fst = mid + 1;
    			}
    			else
    			{
    				lst = mid - 1;
    			}
    		}
    	}
    	
    	cout << ans << '
    ';
    	
        return 0;
    }
  • 相关阅读:
    Django框架文件保存的流程(以及自定义FDFS)
    linux下解决端口被占用的问题
    UNIX 网络编程第三版
    KMP算法
    Java Inner class && nested class
    Java 嵌套作用域
    Java中的blank final
    Java中的接口与抽象类
    error C3163: “_vsnprintf”: 属性与以前的声明不一致
    在某个目录下的所有文件中查找包含某个字符串的Windows命令
  • 原文地址:https://www.cnblogs.com/zeolim/p/12270323.html
Copyright © 2011-2022 走看看