- 吴易繁 的博客
8(八)月(暑期)集训DAY04
- @ 2024-8-8 18:19:34
A. 多项式输出
题目类型:分类讨论
思路
按照题意直接分类讨论即可,我们可以分为以下几种情况来讨论:
- 全为1以上。
- 包含0,1。
- 包含负数。
- 第一项为负数。
- 常数项为零。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e2+10;
int a[N];
int main(){
freopen("poly.in","r",stdin);
freopen("poly.out","w",stdout);
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]!=0&&i!=n+1){
if(i!=1&&a[i]>0) cout<<"+";
if(a[i]==-1) cout<<"-";
if(a[i]!=1&&a[i]!=-1) cout<<a[i];
cout<<"x";
if(i!=n) cout<<"^"<<n-(i-1);
}
}
int b;
cin>>b;
if(b!=0){
if(b>0&&n>0) cout<<"+";
cout<<b;
}
return 0;
}
这道题目我在写的时候忘写一些情况了,所以WA了,下次一定要看清题目。
B. 潜伏者
题目类型:字符串
思路
对于这道题目我们可以用两个数组来分别记录两个字符串中A~Z出现的次数,再用一个字符串来记录密文,再来根据题意来写即可。
代码
#include<bits/stdc++.h>
using namespace std;
int d[30],e[30];
char zm[30];
int main(){
freopen("spy.in","r",stdin);
freopen("spy.out","w",stdout);
string a,b,c;
cin>>a;
cin>>b;
cin>>c;
bool flag=1;
for(int i=0;i<a.size();i++){
d[a[i]-'A']++;
e[b[i]-'A']++;
if(d[a[i]-'A']>1) if(b[i]!=zm[a[i]-'A']) flag=0;
zm[a[i]-'A']=b[i];
}
for(int i=0;i<26;i++) if(d[i]==0||e[i]==0) flag=0;
if(flag==0) cout<<"Failed";
else for(int i=0;i<c.size();i++) cout<<zm[c[i]-'A'];
return 0;
}
本题代码已AC,下一次继续保持。
C. 细胞分裂
题目类型:数学
思路
对于这道题目,我们可以想到:若b是a的倍数,那a的质因数b也有,那么只要一个数组中的数,是另一个数组的倍数,那么就输出所有合法情况的中的最大值,否则输出-1,那么我们可以先求出m1中的质因数与种数,再来判断a[i]是否能把质因数整除,如果可以,就按之前的方法输出所有合法情况的中的最大值,否则的话就continue继续遍历,若最后都没有合法的,就输出-1。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=3e4+10,M=1e4+10;
int a[M],cnt_1[N],cnt_2[N],n,m1,m2;
vector<int> p;
void init(){
for(int i=2;i<=m1;i++){
if(m1%i==0) p.push_back(i);
while(m1%i==0) m1/=i,cnt_1[i]++;
cnt_1[i]*=m2;
}
}
bool check(int x){
memset(cnt_2,0,sizeof cnt_2);
for(int i=0;i<p.size();i++){
if(x%p[i]) return 0;
while(x%p[i]==0) x/=p[i],cnt_2[p[i]]++;
}
return 1;
}
int main(){
freopen("cell.in","r",stdin);
freopen("cell.out","w",stdout);
cin>>n>>m1>>m2;
init();
int mn=2e9;
for(int i=1;i<=n;i++){
cin>>a[i];
if(!check(a[i])) continue;
int mx=0;
for(int j=0;j<p.size();j++) mx=max(mx,(cnt_1[p[j]]+cnt_2[p[j]]-1)/cnt_2[p[j]]);
mn=min(mn,mx);
}
if(mn==2e9) cout<<-1;
else cout<<mn;
return 0;
}
这道题目完全没有思路,所以就放弃了,下一次不能轻易放弃。
D. 道路游戏
题目类型:DP
思路
状态设计:f[i]表示第 i 时刻能够收集的最大金币数cost[i]表示从第i个点购买机器人的花费。
状态转移:f[i] = max(f[i-k] + sum - cost[i-k+1],sum表示从 i - k 走过来搜集的金币总数 第 i 时刻的最大值 = max(i-k时刻的最大值 + 走过来收集的金币 - 买机器人金币)。
注意:机器人购买花费是最后来结算,所以不需要考虑是否买的起的问题。
代码
#include<bits/stdc++.h>
using namespace std;
int g[1005][1005],cost[1005],dp[1005];
int main(){
memset(dp,-2e9,sizeof dp);
int n,m,p;
cin>>n>>m>>p;
dp[0]=0;
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>g[i][j];
for(int i=1;i<=n;i++) cin>>cost[i];
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
int sum=0;
for(int k=1;k<=p&&k<=i;k++){
int last;
if(j-k<=0) last=n+(j-k)%n;
else last=j-k;
sum+=g[last][i-k+1];
dp[i]=max(dp[i],dp[i-k]+sum-cost[last]);
}
}
}
cout<<dp[m];
return 0;
}
这道题目完全没有思路,所以就放弃了,下一次不能轻易放弃。