zoukankan      html  css  js  c++  java
  • Codeforces Round #677 (Div. 3) A-E

    A. Boring Apartments

    模拟

    #include <iostream>
    using namespace std;
    int main()
    {		
    	//freopen("data.txt", "r", stdin);
    	int t;
    	cin >> t;
    	while(t--)
    	{
    
    		int x;
    		cin >> x;
    		int len = 0, num = x % 10;
    		while(x)
    		{
    			len++;
    			x /= 10;
    		}
    		cout << (num - 1) * 10 + (len == 1 ? 1 : (1 + len) * len / 2) << endl;
    	}
    	return 0;
    }
    

    B.Yet Another Bookshelf

    大意是给一个01序列,每次可以选择其中l到r的一段往左或者右平移一格(前提是那个位置为0),问最少多少次能让所有的1均相邻。

    显然答案是第一个1到最后一个1之间的0的个数。

    #include <iostream>
    using namespace std;
    int n, a[55];
    int main()
    {
    	//freopen("data.txt", "r", stdin);
    	int t;
    	cin >> t;
    	while(t--)
    	{
    		cin >> n;
    		for(int i = 1; i <= n; i++) cin >> a[i];
    		int ans = 0;
    		int last = 0;
    		for(int i = 1; i <= n; i++)
    		{
    			if(last)
    			{
    				if(a[i])
    				{
    					ans += i - last - 1;
    					last = i;
    				}
    			}
    			else 
    			{
    				if(a[i]) last = i;
    			}
    		}
    		cout << ans << endl;
    	}
    	return 0;
    }
    

    C.Dominant Piranha

    大意是有n条鱼,每条鱼有一个size,一条鱼可以吃掉相邻的且size小于它的鱼同时自己的size会加一,最后剩下的是鱼王,输出鱼王的编号(没有的话输出-1)。

    容易知道序列仅有一种数时无解,否则一定有解。因为是随意输出,因此可以扫一遍序列找到最大的size,然后从所有size为最大size的鱼里面挑一条能吃掉相邻鱼的即可,因为只要它一开始能吃掉相邻的鱼,它的size就严格大于其他任意鱼了。

    #include <iostream>
    using namespace std;
    int n, a[300005];
    int main()
    {
    	//freopen("data.txt", "r", stdin);
    	int t;
    	cin >> t;
    	while(t--)
    	{
    		cin >> n;
    		a[0] = 0x3f3f3f3f, a[n + 1] = 0x3f3f3f3f;
    		for(int i =1; i <= n; i++) cin >> a[i];
    		int mmax = 0;
    		for(int i = 1; i <= n; i++)
    		{
    			mmax = max(mmax, a[i]);
    		}
    		int cnt = 0, pos = 0;
    		for(int i = 1; i <= n; i++)
    		{
    			if(a[i] == mmax) 
    			{
    				cnt++;
    				if(a[i] > a[i - 1] || a[i] > a[i + 1]) pos = i;
    			}
    
    		}
    		if(cnt == n) cout << -1 << endl;
    		else cout << pos << endl;
    	}
    	return 0;
    }
    

    D.Districts Connection

    大意是给n个点,每个点有一个值,求一个连接n个点的树,并且连边的两个点之间的值不同。

    由于点只有5e3个,直接(O(n^2))扫一遍,把值不同的两个点之间建边扔进vector,然后执行类似kruskal的过程即可(并查集的fa数组记得每次初始化)。

    #include <iostream>
    #include <vector>
    using namespace std;
    int n, a[5005];
    int fa[5005];
    int get(int x)
    {
    	if(x == fa[x]) return x;
    	return fa[x] = get(fa[x]);
    }
    struct edge
    {
    	int x, y;
    };
    int main()
    {
    	//freopen("data.txt","r", stdin);
    	int t;
    	cin >> t;
    	while(t--)
    	{
    		cin >> n;
    		vector<edge> v;
    		for(int i = 1; i <= n; i++) 
    		{
    			cin >> a[i];
    			fa[i] = i;
    		}
    		for(int i = 1; i <= n; i++)
    		{
    			for(int j = i + 1; j <= n; j++)
    			{
    				if(a[i] != a[j]) v.push_back(edge{i, j});
    			}
    		}
    		int cnt = 0;
    		vector<edge> ans;
    		for(int i = 0; i < v.size(); i++)
    		{
    			if(cnt == n - 1)break;
    			int xx = get(v[i].x), yy = get(v[i].y);
    			if(xx == yy) continue;
    			fa[xx] = yy;
    			cnt++;
    			ans.push_back(v[i]);
    		}
    		if(cnt == n - 1)
    		{
    			cout << "YES" << endl;
    			for(int i = 0; i < ans.size(); i++)
    			{
    				cout << ans[i].x << ' ' << ans[i].y << endl;
    			}
    		}
    		else cout << "NO" << endl;
    	}
    	return 0;
    }
    

    E.Two Round Dances

    把1到n这n个数分成两组,问有多少种分法,其中1 4 2 3和4 2 3 1这样的算一种。

    排列组合题,首先挑出来一组,是(C^{frac{2}{n}}_n),这样的话其实两个组的数都能确定下来了,然后是顺序问题,对于每一组,首先是求全排列,但这样还无法排除掉循环的情况(如1 4 2 3和4 2 3 1),因此要除以每组的长度(frac{2}{n}),最后别忘除以2(因为第一组1 4 2 3 第二组5 6 8 7和第二组1 4 2 3 第一组5 6 8 7在题目里算一种)

    #include <iostream>
    using namespace std;
    long long C(int n, int m)
    {
    	if (m < n - m) m = n - m;
    	long long ans = 1;
    	for (int i = m + 1; i <= n; i++) ans *= i;
    	for (int i = 1; i <= n - m; i++) ans /= i;
    	return ans;
    }
    long long f(int n)
    {
    	long long ans = 1;
    	for(int i = 1; i <= n; i++) ans = ans * (1ll * i);
    	return ans;
    }
    int main()
    {
    	//freopen("data.txt", "r", stdin);
    	int n;
    	cin >> n; 
    	cout << C(n, n / 2) * f(n / 2) * f(n / 2) / (n / 2) / (n / 2) / 2;
    	return 0;
    }
    
  • 相关阅读:
    linux开发中常用的命令及技巧(连载)
    使用CCS调试基于AM335X的SPL、Uboot(原创)
    [C语言]变量的声明和定义有什么区别
    C语言中void*详解及应用
    使用中断处理程序实现loop功能
    原码,反码,补码的深入理解与原理
    关于C和C++不同源文件中重名变量的问题(转)
    const extern static 终极指南(转)
    函数调用栈分析
    16位和32位的80X86汇编语言的区别(转)
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/13854365.html
Copyright © 2011-2022 走看看