這次比賽有好幾個題目都不會做,好好學習吧!雖然有很多想法,但是自己一一否定了 0.0
C、 True Love
看懂題目意思就是一個多重揹包,題目只要求染色方案數,使用 bool型多重揹包可以方便解決這個問題。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
int a[200],b[200];
int dp[100100],cnt[100100];
int main(){
int cases,n,m;
scanf("%d",&cases);
for (int cas=1;cas<=cases;cas++){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
for (int i=1;i<=n;i++) scanf("%d",&b[i]);
memset(dp,false,sizeof(dp));
int ans=0;dp[0]=true;
for (int i=1;i<=n;i++){
memset(cnt,0,sizeof(cnt));
for (int j=a[i];j<=m;j++){
if (dp[j-a[i]]&&!dp[j]&&cnt[j-a[i]]<b[i]){
ans++;
dp[j]=true;
cnt[j]=cnt[j-a[i]]+1;
}
}
}
printf("Case %d: %d\n",cas,ans);
}
return 0;
}
D、 LSS
題目求 連續的最多的相同的字母 的個數。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
char st[200];
int main(){
int cases;
scanf("%d",&cases);gets(st);
while (cases--){
gets(st);
int len=strlen(st);
int sum=1,ans=1;
for (int i=1;i<len;i++){
if (st[i-1]==st[i]) sum++;
else sum=1;
if (ans<sum) ans=sum;
}
printf("%d\n",ans);
}
return 0;
}
H、 Salmon and Cat
(a+2)(b+2)=c+2 、 把a+2 、b+2、c+2 看成一個整體,於是題目就變成 求n+2是否被3和5除盡。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int main(){
int n;
while (~scanf("%d",&n)){
n+=2;
while (n%3==0) n/=3;
while (n%5==0) n/=5;
if (n==1) printf("Yes\n");
else printf("No\n");
}
return 0;
}
F、The Arrow
題目大意:
若 sum+t>n ,sum 不變,
若sum+t==n 遊戲結束
若sum+t<n 繼續遊戲,sum+=t。
問,期望多少次 能結束遊戲。
這應該叫 期望dp?
我們設dp[x]表示x還期望走多少步能到達n。顯然 dp[n]=0 、dp[0]就是我們要求解的期望。
方程是 dp[x]=(dp[x+1]+dp[x+2]+...+dp[x+6])/6+1 可以這樣理解,x到x+1 期望走1步,1/6的概率、
和n相鄰的6個點n-1到n-6要注意。以n-2爲例 dp[n-2]=dp[n-1]/6+dp[n]/6+dp[n-2]*4/6+1..爲何要加入dp[n-2]呢?因爲n-2自己可以擲出3-6的話可以得到自己。然後我們解方程就可以得到dp[n-2]...
這便是所謂的期望dp 要倒着來做了吧、在這樣算出來之後,可以考慮正向打表,但是這對於初學者不好理解啊= =、
#include <iostream>
#include <cstring>
#include <cstdio>
#define Maxn 100100
using namespace std;
double dp[Maxn];
int main (){
int cases,n,cnt;
scanf("%d",&cases);
while (cases--){
scanf("%d",&n);
dp[n]=0;
for (int i=n-1;i>=0;i--){
dp[i]=0;cnt=0;
for (int j=1;j<=6;j++){
if (i+j>n) cnt++;
else dp[i]+=dp[i+j];
}
dp[i]=(dp[i]+6)/(6-cnt);
}
printf("%.2f\n",dp[0]);
}
return 0;
}
G、Number Theory
題目大意:所有的數<=222222、給出一個n,和n個數,問有多少對互質的數、
莫比烏斯反演,我還沒怎麼弄明白,以後再來總結。
#include <iostream>
#include <cstring>
#include <cstdio>
#define LL long long
#define Maxn 222222
using namespace std;
bool isPri[Maxn+30];
int mu[Maxn+10],pri[Maxn+10],a[Maxn+10],cnt[Maxn+10],num[Maxn+10];
int pnum;
int mobius(int n){
memset(isPri,true,sizeof(isPri));
pnum=0;isPri[1]=false;mu[1]=1;
for (int i=2;i<=n;i++){
if (isPri[i]){
pri[++pnum]=i;
mu[i]=-1;
}
for (int j=1;j<=pnum;j++){
if (i*pri[j]>n) break;
isPri[i*pri[j]]=false;
if (i%pri[j]==0){
mu[i*pri[j]]==0;
break;
}
mu[i*pri[j]]=-mu[i];
}
}
}
LL cal(LL x){
return x*(x-1)/2;
}
int main(){
mobius(222222);
int n;
while (~scanf("%d",&n)){
int Max=0;
for (int i=1;i<=n;i++){
scanf("%d",&a[i]);
Max=max(Max,a[i]);
}
memset(cnt,0,sizeof(cnt));
memset(num,0,sizeof(num));
for (int i=1;i<=n;i++){
num[a[i]]++;
}
for (int i=1;i<=Max;i++){
for (int j=i;j<=Max;j+=i){
cnt[i]+=num[j];
}
}
LL ans=0;
for (int i=1;i<=Max;i++){
ans+=mu[i]*cal(cnt[i]);
}
printf("%lld\n",ans);
}
return 0;
}
其他還有很多好題目!以後記得一定要補齊。