A:直接判断一下有没有8颗以上糖有就给8颗然后留下来没有就全给了
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
int a[105]
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i++)
scanf("%d",&a[i]);
int ans = 0;
int i;
int pre = 0;
for(i = 1; i <= n; i++){
pre = a[i]+pre;
if(pre>=8){
ans += 8;
pre-=8;
}
else{
ans += pre;
pre = 0;
}
if(ans>=m)
break;
}
if(ans>=m)
printf("%d\n",i);
else
puts("-1");
return 0;
}
B:先把4个的和3个都放中间然后剩下2个的和1个的判断一下就可以了
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int mx = 40005;
int main(){
int n,k,a;
scanf("%d%d",&n,&k);
int s1 = n,s2 = 2*n,q = 0,p = 0;
for(int i = 1; i <= k; i++){
scanf("%d",&a);
while(a>=3){
a-=4;
s1--;
}
a>0?q+=a%2,p+=a/2:0;
}
(p<=s1+s2&&q<=s1*2+s2-p)||(p>s1+s2&&p*2+q<=s1*3+s2*2)?puts("YES"):puts("NO");
//如果两个一样的个数小于等于s1+s2只要满足当p<=s2时 q<=s1*2+s2-p当p>s2时q<=2*(s1+s2-p)+p-s1=s1*2+s2-p
//如果两个一样的个数大于s1+s2同理分情况讨论可以求出p*2+q<=s1*3+s2*2
return 0;
}
C:求每一层一层的求到达最后叶子节点的概率然后就是概率乘于深度,所有总和加起来即可
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int mx = 1e5+5;
int out[mx];
vector<int>g[mx];
double deep[mx];
double ans = 0;
void dfs(int u,double d,double gai,int fa){
deep[u] = d*gai;
double len = g[u].size();
if(len==1&&g[u][0]==fa)
ans+=deep[u];
if(u!=1)
len--;
for(auto v:g[u])
if(v!=fa)
dfs(v,d+1,gai/len,u);
}
int main(){
int n;
scanf("%d",&n);
memset(out,0,sizeof(out));
for(int i = 1; i < n; i++){
int u,v;
scanf("%d%d",&u,&v);
g[v].push_back(u);
g[u].push_back(v);
}
dfs(1,0,1,0);
printf("%.10f\n",ans);
return 0;
}
D:假设是i的倍数的数有c个那么gcd=i的答案sum[i] = c*2^c-1-sum[2*i]-sum[3*i]-....sum[n*i],因为里面包含了gcd等于2*i,3*i,...n*i的个数
然后求一下2到max(a[i])中的每一个sum[i]从最终的答案就是sima(i*sum[i])
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long int ll;
const int mx = 1000005;
const ll mod = 1e9+7;
ll x[mx];
int a[200005];
int T[mx];
int cnt[mx];
ll sum[mx];
int main(){
x[0] = 0;
x[1] = 1;
int n;
for(int i = 2; i < mx; i++)
x[i] = x[i-1]*2%mod;
scanf("%d",&n);
int maxx = 1;
for(int i = 1; i <= n; i++){
scanf("%d",&a[i]);
maxx = max(a[i],maxx);
T[a[i]]++;
}
for(int i = 2; i <= maxx; i++)
for(int j = i; j <= maxx; j+=i)
cnt[i]+=T[j];
for(int i = maxx; i >= 2; i--){
sum[i] = cnt[i]*x[cnt[i]]%mod;
for(int j = 2*i; j <= maxx; j+=i)
sum[i] = ((sum[i]-sum[j])%mod+mod)%mod;
}
ll ans = 0;
for(int i = 2; i <= maxx; i++)
if(sum[i]){
ans = (ans+sum[i]*i)%mod;
// cout<<sum[i]<<endl;
}
printf("%I64d\n",ans);
return 0;
}
E:找出最大的完全图然后每个点平方m,最后的答案就是(m/ans)*(m/ans)*ans*(ans-1)/2
判断这个点加入完全图或者不加入完全图求最大的ans
注意当剩下的点全部加入时候还不能大于ans时候就不用再算下去了,如果这一步不做会超时
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
int map[50][50];
int pre[50];
int ans = 0;
int n,m;
void dfs(int pos,int cnt){
ans = max(ans,cnt);
if(n-pos+cnt+1<=ans) return;
if(pos>n) return;
dfs(pos+1,cnt);
int ok = 1;
for(int i =0; i < cnt; i++)
if(!map[pos][pre[i]]){
ok = 0;
break;
}
if(ok){
pre[cnt++] = pos;
dfs(pos+1,cnt);
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
scanf("%d",&map[i][j]);
ans = 0;
dfs(1,0);
printf("%.10f\n",0.5*m*m*(ans-1)/ans);
}