n转化要*1.0 字符串相等要'0' 泡面要统一不要康师傅 n个顶点最少有n-1条边 /Codeforces 1009 B C - D

/*

Codeforces 1009 B / C / D

划水太久了我...   现在才开始...  真正... 

【别面向数据编程啊啊啊阿吧啊吧】

【也不要,一边看着数据,一边再改,如果可能还是先在小本本上实现了……?】

B题的意思是01换为10  / 21换为12 (可反)

求能得到的最小的

(1)如果按照题目意思的思路,只是简单互换的话,不仅会T到飞起,而且其实完全无法应对201这种()

---所以如何寻找错误样例?-。-  1和2都组合一下,错的不是没有道理的,还能冤枉错了吗?

(2)另寻高见,发现其实1可以到任何位置,0和2的相对位置不能互换。

所以在2之前0最先,1其次,2最后。

然后还要发现如果2后面有1的话,所有的1都可以拿到前面来(因为它可以任意互换,不管左边是0还是1)

这时候写一个简单的小程序就可以实现-.-

但是要注意里面的细节:

(1)字符串里面检验的是‘0’这种  单引号。

(2)for (int j = i + 1; j < s.length(); j++)
                    if (s[j] == '1')c1++;

拿这个来提取后面的1...  里面应该是s[j]....  这种小细节不要跑了不对才去发现啊-.-  这就是能力的差距吧.-

if (count == s.length()-1)这个是跳出循环的条件-.-

最后跑出来当然是s.length()...  但这个judge写在里面就是满足条件的呀

(3)写了 个count。能随手初始化就要初始化成0了好吗。。 没用到的话保不齐哪里又出问题-。-

C题还没怎么搞定... 参考https://blog.csdn.net/wang_123_zy/article/details/81054125

啊。卡到39组数据。。。 这个就是最好一遍算对的。

还有:(直接保留几位)---注意,要是double才可以生效。

【printf("%.15f\n", ans2);】

【printf("%.15f\n", ans2);】

【//cout << fixed << setprecision(8) << ans2 << endl;】

里面用到的n是int,要*1.0

以及,非常坑爹的是:

遇到10000,1,1000,1000这组

最开始写的ans2 += (((n - 1)*(1.0) / 2)*b[i]);

这个会超出范围,但是long long 可以接受

long double范围并没有到1e9,这就没意思了……

所以呢,把n换调约分了,下面会出现误差的。

其中用long long保存,再最后/n误差没那么大了-.-

虽然是int吧..  但是其实除数是(n*(n-1))/2

这种对数字的敏感度....  在这里是不会搞出来误差的-.-

long double还是没用对 啊(大概只是多精确了一点而已吧-.-

唔...   这么改过之后没问题了吧  后面换成printf("%.12Lf\n", (ans2*1.0/n)+ans);

然后因为是奇偶分开的,其实偶数的时候n*n/4 一样没问题.....   2*2都有4了(装死)

(又WA在了9...  天啊这么简单的题-.-)

我总感觉最好一点的方法是接手过来之后好好想清楚了再写。

看着数据改又浪费时间又没意思。

思考自己哪里错了。。。 有些东西还是尽量一遍过去 吧-。-

一上午就搞完昨天的两个题....laji

*/

B

#include<iostream>
#include<string>
using namespace std;
int main() {
	string s;
	int c1, c2, c0;
	while (cin >> s) {
		c1 = 0; c0 = 0; c2 = 0;
		int count=0;
		for (int i = 0; i < s.length(); i++) {
			
			if (s[i] == '0')c0++;
			else if (s[i] == '1')c1++;
			else if (s[i] == '2') {

				for (int j = i + 1; j < s.length(); j++)
				{
					if (s[j] == '1')c1++;
					//cout << "..." << endl;
				}

				for (int j = 1; j <= c0; j++)cout << "0";
				for (int j = 1; j <= c1; j++)cout << "1";
				for (int j = i; j < s.length(); j++) {
					if(s[j]!='1')cout << s[j];

				}cout << endl;
				break;
			}
			count = i;
		}
		//最后出来的时候应该是不满足了,所以就是count+1
		if (count == s.length()-1)//如果没有2
		{
			for (int j = 1; j <= c0; j++)cout << "0";
			for (int j = 1; j <= c1; j++)cout << "1";
			cout << endl;
		}
	}
	return 0;
}
//只要重新排列就可以了,不用记住谁是谁
//啊.. 那就统计吧-.-  位置可以互换的啊啊啊

/*  D

其实也还好///...  但是我最后看着数据搞着搞着竟然还是过了-.-

看着数据.....  啊所以吧其实D也没有想象的那么难的啊

题目的意思是   给你固定的边数和点数  让你构造图 ,其中图里 两条相连的边的最大公约数是1

就这么找就好了……  

有两个需要注意的:

(1)

最开始担心边界会超   但是其实一个地方连一点儿…… 

一个地方连一点儿 极限是10000 个点的话最多是10000条边,边的话其实是绰绰有余的

测试了一下,只不过这个点的总数增长的十分快,到了500左右大约有7k个,(?)800左右已经有10万个了,所以我们直接卡到每次找完它的公因数,然后每次判断一下,如果累计的已经满足了题目的条件直接输出,然后退出就可以。

虽然要判断Impossible吧,但是边已经给到那里了,然后容忍度是有限的,海星。

(2)

有特殊的数据:

【好花絮时间到了……】

我:codeforces的题总是会给你卡到边界!!!有很多题目里类似这样的东西都直接略去了略去了

比如这个题  1 1 的话一个点一条边显然不可能啊  数据就是给了  而我的判断程序又满足了

抽特王:那是你sha

....

还有作为一个图,基本素养!

【n个顶点最多有n-1条边!!!!】

不是回路!是通路!!!! 所以判断情况可以多考虑一下!!!!! 记住了!1!1

*/ 

// D  斗胆...
#include<iostream>
using namespace std;
typedef long long ll;
ll n;
ll m;
int gcd(int a, int b)
{
	while (b)
	{
		int c = a % b;
		a = b;
		b = c;
	}
	return a;
}
int d1[100005];
int d2[100005];
int main() {
	while (cin >> n >> m) {
		long long ans = n-1;
		if (n == 2 && m == 1) {
			cout << "Possible" << endl << "2 1" << endl;
			continue;
		}
		else if (m < n-1 || (m == 1 && n == 1) || (m == 2 && n == 2))
		{
			cout << "Impossible" << endl;
			continue;
		}
		for (int i = 3; i <=n; i++) {
			if(i%2==1)
			for (int j = 1; j < i-1; j++) {
				if (gcd(j, i) == 1) {
					ans++; 
					d1[ans - n+1] = j;
					d2[ans - n+1] = i;
				}
			}
			else if(i%2==0)
				for (int j = 1; j < i-1; j=j+2) {
					if (gcd(j, i) == 1) {
						ans++; //cout << j << " " << i << endl;
						d1[ans - n+1] = j;
						d2[ans - n+1] = i;
					}
				}
			if (ans>=m)
			{
				cout << "Possible" << endl;
				//cout << 1 << " " << n << endl;
				for (int i = 2; i <= n; i++)cout << i - 1 << " " << i << endl;
				//基础的n个吧
				for (int i = 1; i <= m - n + 1; i++)cout << d1[i] << " " << d2[i] << endl;
				break;
			}
		}
		 if (ans < m ) {
			cout << "Impossible" << endl; continue;
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/strongerirene/article/details/81094667