多校J题Jumbled String

题目链接:https://codeforces.com/gym/101933/problem/J这题很有意思。

通过ad值我们可以算出0和1的个数(下面用mn表示),分别为c(a,2)和c(d,2)这个是数学问题不会自己想。比赛的时候傻了用二分求这个数量。其实就是一个方程式a*(a-1)/2=n,那么n通过解方程即为(1+sqrt(8*a+1))/2。(0的解为1,但其实是有问题的)

有一个规律,当你把所有01放两端移动1向前一步(假设000111)那么10个数加一01个数减一,由此我们可以得到01和10个数的和是恒定的,并且等于n*m(数学问题)。

所以只要模拟01位置即可。如果仅使1个一放到最前但还是不满足10个数,那么就移下一个1所以,在开头有10个数/0的个数的1。如果这时,将一部分1放在最前面,其他1放在最后面10个数刚好,那么就成功了,如果还不够,那么就将下一个1往前放(这个1无法到达最前面,他到达的位置就是10的个数%0的个数。1的位置都放好再放0即可。
判断这个是不是可能在于两点:
1.nm是否有解
2.10个数是否等于01个数
在此基础就说明可解即可用第四段方法得解。
几个特别判断:
1.gym里面如果四个数都为0需要输出0而不是不可能
2.000000串和1111111串,这两种情况要么abc都为0要么dbc都为0所以无法用之前方法进行计算。所以需要特判
坑点:
1.特判
2.要先判断nm是否有解
在特判
最后才判断10个数是否等于01个数
(特判必须要符合nm是否有解但是不一定符合10个数是否等于01个数)psgym这道题应该不用多组输入,但是我懒得改了
作为一个菜鸡,我的知识点。。。
1.scanf读入多少数字返回多少数,如果没有读入返回EOF对应的数字为-1,所以有~和!EOF两种写法写成固定数字也可)
2. putchar()向终端输出一个字符。其格式为putchar(ch),
其中ch可以是被单引号(英文状态下)引起来的一个字符,输出该字符(注:该字符也可为转义字符)
可以是介于0~127之间的一个十进制整型数(包含0和127)(超过127就不是ASCII码了),它会被视为对应字符的ASCII代码,输出该ASCII代码对应的字符;65输出A)
也可以是事先用char定义好的一个字符型变量当c为一个被单引号(英文状态下)引起来的字符时,当c为一个事先用char定义好的字符型变量时,输出该变量所指向的字符。
当整型变量ch超出8位变量的范围时,ch则会变强制转化为8位变量(即取其低八位传过去输出),当为负数的时候,由于计算机存储负数是用补码表示的,所以传过去的二进制补码也被当做正数处理,也是取其低八位
getchar()和putchar()函数包含在头文件stdio.h中,使用时需包含此头文件
3.puts()函数用来向标准输出设备(屏幕)输出字符串并换行,其调用方式为,puts(s);其中s为字符串字符(字符串数组名或字符串指针)。代码中是用来空格换行
最后表白写代码的队友,写的真的是又快又好了,很多基本坑(比如之前提到的顺序)也跳了,特判后来也很快反应过来了,而且也写的好快。作为一个给了一些思路的菜鸡希望自己以后不只能提供思路也能打代码。

#include <cstdio>
#include<cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define INF 0x3f3f3f3f
#define debug(x) cout << #x << " = " << x << endl;
using namespace std;
int main(){
 LL a, b, c, d;
 while (scanf("%lld%lld%lld%lld", &a, &b, &c, &d)!=EOF){
  if(a==0&&b==0&&c==0&&d==0) {
   printf("0\n");
  return 0;
 }
LL n=(1+sqrt(8*a+1))/2,m=(1+sqrt(8*d+1))/2;
  if ((n*(n-1) != a*2) || (m*(m-1) != d*2)){
   printf("impossible\n");
   continue;
  }
  if (a != 0 && !b && !c && !d){
   for (int i = 1; i <= n; i++) putchar('0');
   puts("");
   continue;
  }
  if (!a && !b && !c && d != 0){
   for (int i = 1; i <= m; i++) putchar('1');
   puts("");
   continue;
  }
  if (b+c != n*m){
   printf("impossible\n");
   continue;
  }
  LL s = n*m-b;
  for (int i = 1; i <= s/n; i++) putchar('1');
  for (int i = 1; i <= n-s%n; i++) putchar('0');
  if (s % n != 0) putchar('1');
  for (int i = 1; i <= s%n; i++) putchar('0');
  for (int i = 1; i <= m-(s+n-1)/n; i++) putchar('1');
  puts("");
 }
 return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43331783/article/details/88561088
今日推荐