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; }
- 未完,待续...