好久都没打cf了,这次明显感觉手生了不少
A. Arya and Bran
思路:模拟,从前往后模拟送的糖数,若不大于8则全送,否则只送8个剩余保留,送够为止,最后判断一下即可。
其实这次主要就是审题的问题,题目中有一句“before the end”,如果将其直接理解为倒序赠送,那么一上来就是一发wa。
于是赶紧临时改了一波题意
/*
Author Owen_Q
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 110;
int a[maxn];
int main()
{
int n,k;
while(scanf("%d%d",&n,&k)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
int t=0;
int ct;
int leave = 0;
for(ct=0;ct<n;ct++)
{
t++;
leave += a[ct];
if(leave > 8)
{
leave -=8;
k -= 8;
}
else
{
k -= leave;
leave = 0;
}
if(k <=0)
{
break;
}
}
if(ct==n)
{
printf("-1\n");
}
else
{
printf("%d\n",t);
}
}
return 0;
}
C. Journey
思路:这题,典型的dfs寻找路径,由于是n点n-1边,则类似于最小生成树,不会成环,一开始还担心这个,以及只有一个顶点这两个问题,改了很长时间,后来发现这两种情况根本不需要单独考虑。
这题的坑点或许就在路径期望上了,还是需要细心读题,一开始是求总路径长度除以总路径数,后来才发现原来是不同树的深度,加权比重不同,需要每次单独处理,这样就会有大量的运算出现精度误差,与题目给的精度相吻合才十分合理
/*
Author Owen_Q
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
vector <int> ne[maxn];
//bool before[maxn];
bool city[maxn];
double sumlen;
//long long road;
double pi;
void dfs(int id,long long len,double p)
{
int nelen = ne[id].size();
city[id] = true;
int nct = 0;
for(int i=0;i<nelen;i++)
{
if(!city[ne[id][i]])
{
nct ++;
}
}
if(nct>0)
{
double np = p / (double) (nct);
for(int i=0;i<nelen;i++)
{
if(!city[ne[id][i]])
{
//before[id] = true;
dfs(ne[id][i],len+1,np);
}
}
}
else
{
sumlen += len * p;
//cout << id << " " << len << " " << p << endl;
}
/*if(!before[id])
{
sumlen += len;
//road++;
}*/
/*city[id] = false;
before[id] = false;*/
return ;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
memset(city,false,sizeof(city));
//memset(before,false,sizeof(before));
for(int i=1;i<=n;i++)
{
ne[i].clear();
}
sumlen = 0;
//road = 0;
pi = 1.0;
for(int i=0;i<n-1;i++)
{
int a,b;
scanf("%d%d",&a,&b);
ne[a].push_back(b);
ne[b].push_back(a);
}
dfs(1,0,1.0);
//double re = (double)(sumlen) / (double)(road);
/*if(road!=0)
{
re = (double)(sumlen) / (double)(road);
}
else
{
re = 0;
}*/
//cout << sumlen << " " << road << " ";
printf("%.15lf\n",sumlen);
}
return 0;
}
B. Game of the Rows
思路:这题看似简单,就是寻找一种排座位的贪心思路,实则坑点十足啊
首先,还是审题,中间位置的图不是白画的,看图才能更直观得理解
这题,比较简单的思路就是先将能坐满4个人的座位坐满,将所有队模4,简化问题,并保证剩余4座数不小于0,将多余的人强制加在2座上
由于这题时间较为宽松,排个序会使问题更加简单
然后简化的问题分四种情况,座位分为三种:四座,两座和剩两空以上的四座(以下简称空座)
3人坐先往四座上排,一组一座;坐满则往二座上排,一组两座
2人坐先往两座上排,一组一座;坐满则往四座上排,一组一座,并产生一个空座;再做满则往空座上坐,一组两座
1人坐先往空座上坐,一组一座;坐满组往两座上座,一组一座;再坐满则往四座上排,一组一座,并产生一个空座
0人坐,解决
2人坐以及空座均为易忽略点,此题要想全确实不易啊
/*
Author Owen_Q
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 110;
int a[maxn];
int main()
{
int n,k;
while(scanf("%d%d",&n,&k)!=EOF)
{
int sit4 = n;
int sit2 = 2*n;
int block = 0;
for(int i=0;i<k;i++)
{
scanf("%d",&a[i]);
}
/*for(int i=0;i<k;i++)
{
cout << a[i] << endl;
}*/
for(int i=0;i<k;i++)
{
sit4 -= (a[i]/4);
a[i] %= 4;
}
sort(a,a+k,greater<int>());
if(sit4<0)
{
sit2 += sit4 * 2;
sit4 = 0;
}
/*cout << "sit4" << sit4 << endl;
for(int i=0;i<k;i++)
{
cout << a[i] << endl;
}*/
//int i;
for(int i=0;i<k;i++)
{
if(a[i]==3)
{
if(sit4>0)
{
sit4--;
}
else
{
sit2 -= 2;
}
}
else if(a[i]==2)
{
if(sit2>0)
{
sit2--;
}
else
{
if(sit4>0)
{
sit4--;
block++;
}
else
{
block -= 2;
}
}
}
else if(a[i]==1)
{
if(block>0)
{
block--;
}
else if(sit2>0)
{
sit2--;
}
else
{
sit4--;
block++;
}
}
a[i] = 0;
/*if(sit2<0)
{
sit2 = 0;
sit4--;
}
if(sit2 == 0)
{
break;
}*/
}
/*cout << "sit2" << sit2 << endl;
for(int i=0;i<k;i++)
{
cout << a[i] << endl;
}*/
/*sit4 *= 2;
for(int j=i;j<k;j++)
{
if(a[j]>0)
{
a[j] = 0;
sit4--;
}
}*/
/*cout << "sit4" << sit4 << endl;
for(int i=0;i<k;i++)
{
cout << a[i] << endl;
}*/
if(sit2>=0&&sit4>=0&&block>=0)
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
return 0;
}