Codeforces Round #696 (Div. 2)题解
题目分析
要使得到的d最大
1:d的位数必然同样为n位,不能因为有连续的相同数导致位数减少
2:从最高位开始,每一位都尽可能的大,无需考虑后效性,因为越高位的数越大,d越大
代码实现:
循环控制每一位,从最高位开始,用k记录上一位d为多少,根据k的值和b的每一位值,决定a的该位值为多少,并重新更新k,例如:当k=1或者k=0时,若b[i]为1,则a[i]为1,k更新为2。
#include<iostream>
using namespace std;
char b[105000];
int main(){
int T,n;
cin>>T;
while(T--){
cin>>n;
cin>>b;
int k=0;
for(int i=0;i<n;i++){
if(b[i]=='1'){
if(k==0){
cout<<1;
k=2;
}
else if(k==1){
cout<<1;
k=2;
}
else if(k==2){
cout<<0;
k=1;
}
}
else{
if(k==1){
cout<<0;
k=0;
}
else if(k==2){
cout<<1;
k=1;
}
else if(k==0){
cout<<1;
k=1;
}
}
}
cout<<endl;
}
return 0;
}
题目分析
d至少已有两个因子:1和它本身
d还需要两个因子,
设这两个因子为x,y
且x<y
可以发现,x不能为合数,因为x的因子也为d的因子,这样就导致d有比x更小的因子t,若t满足条件2,则x直接修改为t即可,这样可以使得答案更小,所以x不能为合数。同理y也不能为合数。那么答案就是求得两个满足条件2的最小素数x,y,答案即为xy
代码实现
线性筛预处理出所有素数,lowerbound查找两个最小素数,相乘输出即可
#include<iostream>
#include<algorithm>
using namespace std;
long long prime[10000005],p[10000005],cnt,N=10000000;
void init(){
p[0]=p[1]=1;
for(int i=2;i<=N;i++){
if(p[i]==0)prime[++cnt]=i;
for(int j=1;j<=cnt;j++){
if(prime[j]*i>N)break;
p[prime[j]*i]=1;
if(i%prime[j]==0)break;
}
}
}
int main() {
int T,n;
init();
cin>>T;
while(T--) {
cin>>n;
long long x=prime[lower_bound(prime+1,prime+cnt+1,1+n)-prime];
long long y=prime[lower_bound(prime+1,prime+cnt+1,x+n)-prime];
cout<<x*y<<endl;
}
return 0;
}
题目分析
答案x必然为数组中最大数up与数组中其他数的和
第一步:枚举另一个数
第二步:每次都用up成为两个数的和,并将up更新为两个数的较大数,易知这两个数中的某一个数一定为比up小的次大数,不然该次大数与任何数的和,都比该轮两个数比较成的新的up值大,就无法在后续的操作中被用掉了
代码实现
第一步:循环枚举
第二步:用multiset存储除了枚举掉的那个数的其他数据,循环执行以下操作:从最大值开始寻找次大值,将他们的差的数值的计数器减1,并更新最大值为次大值,无法减时,该轮失败
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
int a[5000],b1[5000],b2[5000],top;
multiset<int>s;
int main() {
int T, n,ans;
cin>>T;
while (T--) {
cin>>n;
for (int i=1;i<=2*n;i++)cin>>a[i];
sort(a+1,a+2*n+1);
for(int i=1;i<2*n;i++){
top=0;
b1[++top]=a[2*n];
b2[top]=a[i];
int up=a[2*n];
s.clear();
for(int j=1;j<2*n;j++){
if(j!=i)s.insert(a[j]);
}
multiset<int>::iterator it1,it2;
while(!s.empty()){
it1=s.end();
it1--;
int temp=*it1;
s.erase(it1);
it2=s.find(up-temp);
if(it2!=s.end()){
s.erase(it2);
b1[++top]=temp;
b2[top]=up-temp;
up=temp;
}
else{
break;
}
}
if(top==n){
break;
}
}
if(top==n){
cout<<"YES"<<endl;
cout<<b1[1]+b2[1]<<endl;
for(int i=1;i<=top;i++){
cout<<b2[i]<<" "<<b1[i]<<endl;
}
}
else cout<<"NO"<<endl;
}
return 0;
}