A 咪咪游戏
题意:判断一个字符串是否由只mq构成(之前在中石大OJ上做过一个类似的,比这个难些,然后我就按着上次那样去做,结果wa了。。嘤嘤嘤... (其实这道题还是蛮简单的。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
inline ll read(){//快读,可以不用
ll x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return 1ll*x*f;
}
const int maxn=1e5+5;
int n;
char s[maxn];
int main(){
n=read();//不用快读的话可以换成cin或者scanf
while(n--){
scanf("%s",s);
int len=strlen(s),flag=1;//flag起记录作用
if(len&1) printf("No\n");//字符串的长度必须为偶数
else{
for(int i=0;i<len-1;i+=2)
if(s[i]!='m'||s[i+1]!='q'){//碰到不是以mq循环的
flag=0;//记录下来
break;//终止循环
}
if(flag) printf("Yes\n");
else printf("No\n");
}
}
return 0;
} B 三角形
题意:有n个箱子,每个箱子里有a[i][0]件物品,给出每件物品的价值,每个箱子中选一件物品,求前k项最小价值的和。
思路:这道题只需要算出不同价值对应的方案数就可以了,用f[i][j]表示取i件总价值为j的物品的方案数,然后从小到大按价值枚举相加就行了。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
inline ll read(){//快读
ll x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return 1ll*x*f;
}
const int maxn=1e4+5;
ll n,k,ans,a[105][105],f[105][maxn];
int main(){
n=read(),k=read();
for(int i=1;i<=n;i++){
a[i][0]=read();//该箱子里的物品数
for(int j=1;j<=a[i][0];j++) a[i][j]=read();
}
f[0][0]=1;//好多题都是这样规定的
for(int i=1;i<=n;i++)
for(int j=1;j<=a[i][0];j++)
for(int p=a[i][j];p<=10000;p++){
f[i][p]+=f[i-1][p-a[i][j]];
f[i][p]=min(f[i][p],k);//方案数不能超过k
}
ll minn;
for(int i=1;i<=10000;i++)//价值从1到10000
if(f[n][i]){//如果存在该方案
minn=min(k,f[n][i]);
k-=minn;
ans+=minn*i;
}
printf("%lld\n",ans);
return 0;
} C 区间加
题意:给定一个序列,每次对序列的一个区间加一,最后使得区间内的所有数都等于m,求有多少种方法。
思路:每一个区间都有左端点和右端点,且每个点只能用一次,用cnt记录现在还没有匹配的区间左端点的个数,用a[i]表示第i个点到m还需要加多少。则有以下结论:
1、a[i]-a[i-1]=-1,说明第i个点比第i-1个点需要加的次数少,则把右端点放在i-1处,此时左面有cnt个左端点,结果乘cnt,放后少了一个左端点,cnt--;
2、a[i]-a[i-1]=1,说明第i个点比第i-1个点需要加的次数多,则把左端点放在i处,++cnt;
3、a[i]==a[i-1],说明第i个点比第i-1个点需要加的次数相等,那么可以在i-1处放左端点,在i处放右端点,也可以不什么都不放,因此结果乘cnt+1。因为左端点数减一,右端点数加一,所以cnt不变。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
inline ll read(){
ll x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return 1ll*x*f;
}
const int maxn=2e3+5;
const ll mod=998244355;
ll n,m,ans=1,cnt,a[maxn];
int main(){
n=read(),m=read();
for(int i=1;i<=n;i++) a[i]=m-read();
for(int i=n+1;i>=1;i--) a[i]-=a[i-1];
for(int i=1;i<=n;i++){
if(abs(a[i])>1){//不能有差大于2的,因为任意两次区间加的起始,结束位置各不相同
printf("0\n");
return 0;
}
if(a[i]==-1) ans=(ans*cnt--)%mod;
else if(a[i]==1) ++cnt;
else ans=(ans*(cnt+1))%mod;
}
printf("%lld\n",ans);
return 0;
} - 未完,待续...

京公网安备 11010502036488号