奋斗群群赛—8
T1:k-Factorization
题目位置:
题意:
给你一个数字n与m,能输出将n分解为m个大于1的数的乘积,输出其中的一种就好!
不能就输出-1来表示不行
AC代码:
#include <bits/stdc++.h>
using namespace std;
int k1[100005];
int f(int x)
{
for(int i=2; i<=x; i++)
if(x%i==0)
return i;
}
int main()
{
int n,k,tot=0;
cin>>n>>k;
while(tot!=k-1&&n!=1)
{
k1[tot]=f(n);
n/=f(n);
tot++;
}
if(tot==k-1&&n!=1)
{
for(int i=0; i<tot; i++)
cout<<k1[i]<<" ";
cout<<n;
}
else
{
cout<<-1;
}
}
小反思:
无,只要稍微想想就好了!
T2:Odd sum
题目位置:
题意:
给你n个数字,求一个子集,使得子集内部的和为奇数而且值是最大的,输出这个值
AC代码:
#include <bits/stdc++.h>
using namespace std;
int a[100005];
int main()
{
int n,inf=999999;
long long int tot=0;
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
if(a[i]>=0)
tot+=a[i];
}
if(tot%2==1)
{
cout<<tot<<endl;
return 0;
}
else
{
for(int i=1; i<=n; i++)
if(abs(a[i])<inf&&abs(a[i])%2==1)
inf=abs(a[i]);
cout<<tot-inf;
}
return 0;
}
T3:Minimal string
题目位置:
题意:
意思简单点就是一个字符串s,利用一个栈来使得这个新的字符串的字典序最小,求着个字符串.其实一开始就要预处理,预处理什么呢?就是在第i位,输出i~n位的字符串中的最小的字符就好了!那么有人会问:要不要全盘扫啊?其实不需要的,只要从n开始–来比较相邻的就可以了!
m[len]=inf;
for(int i=len-1; i>=0; i--)
{
m[i]=min(m[i+1],s[i]);
}
AC代码:
手写栈的程序:
#include <bits/stdc++.h>
using namespace std;
const int MAX=100100;
const int inf='z'+1;
char s[MAX],t[MAX],m[MAX];
int main()
{
string s;
cin>>s;
int len=s.length();
m[len]=inf;
for(int i=len-1; i>=0; i--)
{
m[i]=min(m[i+1],s[i]);
}
int j=0;
for(int i=0; i<len; i++)
{
t[j]=s[i];
j++;
while(j>0&&t[j-1]<=m[i+1])
{
cout<<t[--j];
}
}
return 0;
}
系统自带栈的程序:
#include <bits/stdc++.h>
#include <stack>
using namespace std;
const int MAX=100100;
const int inf='z'+1;
char s[MAX],t[MAX],m[MAX];
stack <int> my_stack;
int main()
{
string s;
cin>>s;
int len=s.length();
m[len]=inf;
for(int i=len-1;i>=0;i--)
{
m[i]=min(m[i+1],s[i]);
}
int p=0;
while(my_stack.empty()==0||p<len)
{
while(my_stack.empty()==0&&my_stack.top()<=m[p])
{
cout<<(char)my_stack.top();
my_stack.pop();
}
if(len==p) break;
my_stack.push(s[p]);
p++;
}
}
T4:Broken BST
题目位置:
题意:
AC代码:
T5:Array Queries
题目位置
题意:
有n个整数,有这样的询问,给你m个询问,每个询问有2个数,分别为p,k.
有这样的while循环,p=p+a[p]+k;直到p>n为止,然后输出了次数,求其值!
其实仔细想就会发现k是影响较大的数字,如果k小的话,就会导致while循环执行了太多的次数了,所以不怕k的值大,就怕k小!,所以要预处理k小的值!
dp为:
for(int k=1; k<=line; k++)
for(int i=n; i>=1; i--)
{
if(k+a[i]+i>n)
f[k][i]=1;
//cout<<f[i][j];
else //p=p+k+a[p] i->p
{
int r=i+k+a[i];
f[k][i]=f[k][r]+1;
}
}
AC代码:
#include <bits/stdc++.h>
using namespace std;
const int line=500,N=100005;
int a[N],f[505][N];
int main()
{
//k 1~line up!
int n,m,x,k1;
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
//´Ómax¿ªÊ¼ÏòÏÂ--; //ö¾Ù+1¾ÍºÃ!!!
for(int k=1; k<=line; k++)
for(int i=n; i>=1; i--)
{
if(k+a[i]+i>n)
f[k][i]=1;
//cout<<f[i][j];
else //p=p+k+a[p] i->p
{
int r=i+k+a[i];
f[k][i]=f[k][r]+1;
}
}
scanf("%d",&m);
for(int v=1; v<=m; v++)
{
scanf("%d%d",&x,&k1);
int time=0,p=x;
if(k1<=line)
{
cout<<f[k1][x]<<endl;
continue;
}
else
while(p<=n)
{
p=p+a[p]+k1;
time++;
}
cout<<time<<endl;
}
return 0;
}
总结:
1.善于预处理
2.发现简单易行的方法!