[toc]
https://vjudge.net/contest/184566#problem
A - k-Factorization CodeForces - 797A
题意
- 给出两个数n,k,问能否将n分成k个数相乘.
题解
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,k;cin>>n>>k;
int dvs[100000]={0},p=0,ans=0;
int nn=n;
for(int i=2;i<=nn;i++){
while(nn%i==0){
nn/=i;
ans++;
dvs[++p]=i;
}
}
if(ans<k){
cout<<"-1\n";
return 0;
}
for(int i=1;i<k;i++){
cout<<dvs[i]<<' ';
n/=dvs[i];
}
cout<<n;
}
B - Odd sum CodeForces - 797B
题意
- 给出一个数列,求其中和最大且为奇数的子序列.
题解
#include<bits/stdc++.h>
using namespace std;
int n,a[100005],sum,len,posi=10000,nega=-10000;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(a[i]>0&&a[i]&1)posi=min(posi,a[i]);
if(a[i]<0&&a[i]&1)nega=max(nega,a[i]);
if(a[i]>0)
{
sum+=a[i];
len++;
}
}
if(sum&1)
{
cout<<sum;
return 0;
}
else
{
int t1,t2;
t1=sum-posi;
t2=sum+nega;
cout<<max(t1,t2);
}
}
C - Minimal string CodeForces - 797C
题意
- 把一个字符数组中的字符通过一个栈转移到另一个字符数组中,使得到的字符串字典序最小.
思路
- 预处理原数组,
char best[N];
best[n]='z';
for(int i=n-1;i>=0;i--)
{
best[i]=min(best[i+1],s[i]);
}
- 即直接往答案数组中放的第i个数要等于best[i].
题解
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
const int N=1e5+5;
int main()
{
char s[N];
gets(s);
int n=strlen(s);
char best[N];
best[n]='z';
for(int i=n-1;i>=0;i--)
{
best[i]=min(best[i+1],s[i]);
}
stack<char>v;
int cur=0;
while(!v.empty()||cur<n)
{
if(!v.empty()&&v.top()<=best[cur])
{
putchar(v.top());
v.pop();
}
else v.push(s[cur++]);
}
cout<<endl;
return 0;
}
D - Broken BST CodeForces - 797D
题意
- 一棵二叉树,把它当二叉搜索树操作,求不能搜索到的结点的值数.
思路
- 用map完成去重操作,因为拥有一个值的多个结点,其中只要有一个能被搜索到,这个值就能被搜索到.
题解
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
const int INF=0x3f3f3f3f;
int val[maxn];
int l[maxn],r[maxn];
int id[maxn];
map<int,int>M;
void dfs(int s,int mi,int ma){
if(val[s]>mi&&val[s]<ma)M[val[s]]=1;
if(l[s]!=-1)dfs(l[s],mi,min(ma,val[s]));
if(r[s]!=-1)dfs(r[s],max(mi,val[s]),ma);
}
int main(){
int n;
scanf("%d",&n);
memset(id,0,sizeof(id));
for(int i=1;i<=n;++i){
scanf("%d%d%d",&val[i],&l[i],&r[i]);
if(l[i]!=-1)id[l[i]]++;
if(r[i]!=-1)id[r[i]]++;
}
int root;
for(int i=1;i<=n;++i){
if(!id[i])root=i;
}
int ans=0;
dfs(root,-1,INF);
for(int i=1;i<=n;++i)if(!M[val[i]])ans++;
printf("%d\n",ans);
return 0;
}
E - Array Queries CodeForces - 797E
a is an array of n positive integers, all of which are not greater than n.
You have to process q queries to this array. Each query is represented by two numbers p and k. Several operations are performed in each query; each operation changes p to p + ap + k. There operations are applied until p becomes greater than n. The answer to the query is the number of performed operations.
Input
The first line contains one integer n (1 ≤ n ≤ 100000).The second line contains n integers — elements of a (1 ≤ ai ≤ n for each i from 1 to n).
The third line containts one integer q (1 ≤ q ≤ 100000).
Then q lines follow. Each line contains the values of p and k for corresponding query (1 ≤ p, k ≤ n).
Output
Print q integers, ith integer must be equal to the answer to ith query.Example
Input
3
1 1 1
3
1 1
2 1
3 1
Output
2
1
1
Note
Consider first example:In first query after first operation p = 3, after second operation p = 5.
In next two queries p is greater than n after the first operation.
思路
- k在一定范围以内,记忆化搜索;k在范围外,暴力.
题解
#include<bits/stdc++.h>
using namespace std;
const int N=100010,V=500;
int n,q,p,k,i,a[N],dp[N][V],ans[N];
int f(int x,int y){
if(x>n)return 0;
if(y<V){
if(dp[x][y])return dp[x][y];
return dp[x][y]=f(x+a[x]+y,y)+1;
}
return f(x+a[x]+y,y)+1;
}
int main(){
for(cin>>n,i=1;i<=n;i++)cin>>a[i];
for(cin>>q,i=1;i<=q;i++){
cin>>p>>k;
ans[i]=f(p,k);
}
for(i=1;i<=q;i++)cout<<ans[i]<<endl;
}
F - Mice and Holes CodeForces - 797F
>
>
>
>
>
>
>
>
>
>
>