首页 > 代码库 > Topcoder SRM 648 Div2 1000
Topcoder SRM 648 Div2 1000
Topcoder SRM 648 Div2 1000
Problem
给一个长度为N的字符串S,S只含有‘A’、‘B‘、‘C‘三种元素。给定一个K,要求返回字符串S,使得S中恰好有K对pair(i,j)满足 0=<i<j<N,且 S[i]<S[j]。若不存在,则返回空串。
Limits
Time Limit(ms): 2000
Memory Limit(MB): 256
N: [3, 30]
K: [0, N*(N-1)/2 ]
Solution
设S中含有n1个‘A’,n2个‘B’,n3个‘C‘,设num=n1*n2+n1*n3+n2*n3,num即为S中pair的总数;先O(N^3)求出n1,n2,n3以及num 使得n1+n2+n3=N 且 num最大。若K>num,则不存在;否则一定存在,用插空法求出即可。
More
简单阐述如何用插空法求S。先假设S含有n1个‘A‘,然后将n2个‘B‘适当插入S,再将n3个‘C‘适当插入S。
关于插空法的具体做法以及为何 ”K>num则不存在“,请看上篇文章,Div1 250与Div2 1000方法一致。
Complexity
Time Complexity: O(N^3)
Memory Complexity: O(N)
Source
Topcoder SRM 648 Div2 1000
Code
Topcoder SRM 648 Div2 1000 From My Github
代码如下:
#include<cstdio> #include<cstring> #include<string> #include<cstdlib> using namespace std; class ABC{ public: int num[40]; bool isA[40]; string createString(int n, int k){ int n1=0,n2=0,n3=0,nt=-1; for(int i1=0;i1<n;i1++){ for(int i2=0;i2<n;i2++){ for(int i3=0;i3<n;i3++){ if(i1+i2+i3==n){ if(i1*i2+i1*i3+i2*i3>nt){ nt=i1*i2+i1*i3+i2*i3; n1=i1,n2=i2,n3=i3; } } } } } if(k>nt) return "";//判断无解 //先往“AAA..”中插入'B' string s; s.clear(); memset(num,0,sizeof(num)); nt=n2; while(k && nt){ int kt=min(n1,k); num[kt]+=1; k-=kt; nt-=1; } for(int i=0;i<nt;i++){ s+="B"; } for(int i=1;i<=n1;i++){ s+="A"; while(num[i]--){ s+="B"; } } for(int i=0;i<n1+n2;i++){ isA[i]=s[i]=='A'?true:false; } //再插入'C' memset(num,0,sizeof(num)); nt=n3; while(k && nt){ int kt=min(n1+n2,k); num[kt]+=1; k-=kt; nt-=1; } s.clear(); for(int i=0;i<nt;i++){ s+="C"; } for(int i=1;i<=n1+n2;i++){ s+=isA[i-1]?"A":"B"; while(num[i]--){ s+="C"; } } return s; } };
Topcoder SRM 648 Div2 1000
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。