欢迎来到就算过了一载春秋的博客

不管过了几载春秋,我还是会偶尔想起。

J-Jumbled String(2018NCPC)

VJ上题目链接:https://vjudge.net/problem/Kattis-jumbledstring 

 

看题目以为是关于字符串匹配的,理解后发现原来是关于计数的?

给定a、b、c、d四个整数,求一个01串,要求该串能找到a个00,b个01,c个10,d个11。(子序列,不必连续)

根据a个00是能求出0的个数x的,因为x个0组成的串中任意拿两个0即是C(x,2)=x*(x-1)/2个。1的个数y同理可求。

即解方程x*x-x-2*a=0和y*y-y-2*d=0。有一个无解则"impossible"。

接下来是安排01和10。

求出x和y后就能知道所有的长度为2的子序列个数即C(x+y,2),又长度为2的子序列的个数和是a+b+c+d,联立上式可得:b+c=x*y。若不满足则impossible。满足则说明有解。

只考虑01和10,每将1个'1'排在p个'0'后会增加p个01的子序列,x-p个10的子序列。

 

 1 #include<iostream>
 2 #include<sstream>
 3 #include<fstream>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<iomanip>
 7 #include<cstdlib>
 8 #include<cctype>
 9 #include<vector>
10 #include<string>
11 #include<cmath>
12 #include<ctime>
13 #include<stack>
14 #include<queue>
15 #include<map>
16 #include<set>
17 #define mem(a,b) memset(a,b,sizeof(a))
18 #define random(a,b) (rand()%(b-a+1)+a)
19 #define ll long long
20 #define ull unsigned long long
21 #define e 2.71828182
22 #define Pi acos(-1.0)
23 #define ls(rt) (rt<<1)
24 #define rs(rt) (rt<<1|1)
25 #define lowbit(x) (x&(-x))
26 using namespace std;
27 ll read()
28 {
29     int s=1,x=0;
30     char ch=getchar();
31     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
32     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
33     return x*s;
34 }
35 ll cal(ll ad)//x*x-x-2*a=0
36 {
37     if(ad==0) return 1;
38     ll delta=sqrt(1+8*ad);
39     if(delta*delta!=1+8*ad) return -1;
40     return (1+delta)/2;
41 } 
42 int main()
43 {
44     ll a=read(),b=read(),c=read(),d=read(); 
45     if(a==0&&b==0&&c==0&&d==0) return 0*printf("0\n"); 
46     ll x=cal(a),y=cal(d);
47     if(x==-1||y==-1) return 0*printf("impossible\n");
48     if(x==1&&y==1)
49     {
50         if(b&&c)    printf("impossible\n");
51         else if(b==1)    printf("01\n");
52         else if(c==1)    printf("10\n");
53         else if(b==0&&c==0) printf("0\n");
54         else printf("impossible\n");
55         return 0;
56     }
57     else if(x==1)
58     {
59         if(b==0&&c==0)x=0;
60     }
61     else if(y==1)
62     {
63         if(b==0&&c==0)y=0;
64     }
65     if(x*y!=b+c) return 0*printf("impossible\n");
66     string ans(x,'0');
67     ll left_01=b;//还有left_01个子序列未构成 
68     while(y--)
69     {
70         ll ip=min(left_01,x);//insert_pos == 01
71         ans.insert(ip,"1");//因为ip是非递增的,所以这里用insert不用担心 
72         left_01-=ip;
73     }
74     cout<<ans<<endl;
75 }
View Code

(注意特判一些特殊情况)

posted on 2019-08-06 16:34  就算过了一载春秋  阅读(332)  评论(0)    收藏  举报

导航