A:水题
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cstring>
#include<set>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
const int mx = 1e4+5,mod = 1e9+7;
int n,m,a[mx];
int main(){
scanf("%d%d",&n,&m);
int ans = 0;
for(int i=1;i<=n;i++) scanf("%d",a+i);
for(int i=1;i<=n;i++){
if(a[i]>8) { a[i+1]+= a[i]-8, a[i] = 8; }
m -= a[i];
ans++;
if(m<=0) break;
}
if(m>0) puts("-1");
else printf("%d\n",ans);
return 0;
}
B:先考虑将中间四个填满,不能刚好填满的先放着,然后在将前后填满,剩一个的也先留着,然后最后再去将这些填剩下的四个空座拿去填,1和2做好弄成差不多,就能尽可能的多放。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cstring>
#include<set>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
const int mx = 1e4+5,mod = 1e9+7;
int n,m,a[mx/10],id[4];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++) scanf("%d",a+i);
int cnt = 2*n;
for(int i=1;i<=m;i++){
int v = a[i]/4;
if(n>=v) { n -= v; a[i] = a[i]%4; continue; }
a[i] = a[i] - n*4, n = 0;
}
for(int i=1;i<=m&&cnt;i++){
int v = a[i]/2;
if(a[i]&1) id[1]++;
if(cnt>=v) { cnt -= v,a[i] = 0; continue; }
a[i] = a[i] - cnt*2 , cnt = 0;
}
if(cnt){
if(cnt+2*n>=id[1]) puts("YES");
else puts("NO");
return 0;
}
for(int i=1;i<=m;i++){
if(a[i]>=4) { puts("NO"); return 0; }
id[a[i]]++;
}
n -= id[3];
if(id[2]>id[1]){
int v = id[2] - id[1];
v = v/2;
id[2] -= v;
id[1] += 2*v;
}
int x = min(id[1],id[2]);
n -= x , id[1] -= x , id[2] -= x;
n -= id[2];
n -= (id[1]+1)/2;
puts(n<0? "NO":"YES");
return 0;
}
C:不管怎么走最后都是到叶子的,所以暴力就行了。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cstring>
#include<set>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
const int mx = 1e5+5,mod = 1e9+7;
int n,m,in[mx],deep[mx];
double val[mx];
vector<int>vec[mx];
void dfs(int x,int f){
for(int i=0;i<vec[x].size();i++){
int son = vec[x][i];
if(son==f) continue;
deep[son] = deep[x] + 1;
val[son] = val[x]*1.0/(vec[x].size()-1);
dfs(son,x);
}
}
int main(){
scanf("%d",&n);
int a,b;
deep[1] = 0;
for(int i=1;i<n;i++){
scanf("%d%d",&a,&b);
in[a]++ , in[b]++;
vec[a].push_back(b);
vec[b].push_back(a);
}
vec[1].push_back(0);
val[1] = 1;
dfs(1,0);
double ans = 0;
for(int i=1;i<=n;i++){
if(in[i]==1) ans += val[i]*deep[i];
}
printf("%.7f\n",ans);
return 0;
}
D:容斥之前需要先算出一个公式那就是k*2^(k-1),k代表x的倍数个数,就是公约数包含x的最多个数,这个根据组合项前后项合并很容易得到。然后就是直接容斥啦。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cstring>
#include<set>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
const int mx = 1e6+5,mod = 1e9+7;
int n,m,val[mx],cnt[mx],a[mx];
typedef long long ll;
int main(){
val[0] = 1;
ll ans = 0;
scanf("%d",&n);
for(int i=1;i<=n;i++) val[i] = 2*val[i-1]%mod;
for(int i=1;i<=n;i++) scanf("%d",&m),cnt[m]++;
for(int i=mx;i>=2;i--){
int p = i,sum = 0;
while(p<mx) sum +=cnt[p],p += i;
p = i+i;
a[i] = (1ll*sum*val[sum-1])%mod;
while(p<mx) a[i] = (a[i]-a[p]+mod)%mod, p += i;
ans = (ans+1ll*a[i]*i)%mod;
}
printf("%I64d\n",ans);
return 0;
}