/*
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;
}