codeforces的分好久都没有变化了,而这场,修仙过度加上状态全无,降分没商量啊,来看看吧
A. Greed
思路:倾倒可乐,问能否将所有可乐倒入两个瓶子内
这个其实不要被题目内部剩余容量和总容量搞混淆就行了,并没有什么复杂计算,纯粹的水题
累加a计算总和,统计b,取最大值与次大值,然后比较就行了
很多时候,都是自己把事情搞复杂的
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 1e5+10;
int a[maxn],b[maxn];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
long long sum = 0;
long long max1 = 0, max2 = 0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
sum += a[i];
}
for(int i=0;i<n;i++)
{
scanf("%d",&b[i]);
if(b[i]>max2)
{
max2 = b[i];
}
if(max2>max1)
{
long long temp = max1;
max1 = max2;
max2 = temp;
}
}
sum -= max1 + max2;
if(sum>0)
{
printf("NO\n");
}
else
{
printf("YES\n");
}
}
return 0;
}
B. Wrath
思路:这题有点类似于区间覆盖问题,每个点都可以向前覆盖一段距离,问有多少点没有被覆盖
其实这题思路也很清晰,按区间头排序,以一个指针向后便利,即可得到结果
就是要注意一下区间边界什么的,最后数组数据范围千万不能乱搞啊,大意失荆州
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 1e6+10;
typedef struct KILL
{
int st;
int en;
}Kill;
Kill k[maxn];
bool cmp(const Kill &a, const Kill &b)
{
if(a.st<b.st)
{
return true;
}
else
{
return false;
}
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int sum = 0;
int temp;
scanf("%d",&temp);
for(int i=1;i<n;i++,sum++)
{
k[sum].en = i - 1;
scanf("%d",&temp);
k[sum].st = i - temp;
if(k[sum].st<0)
{
k[sum].st = 0;
}
if(temp == 0)
{
sum--;
}
}
//cout << sum << "*" << endl;
sort(k,k+sum,cmp);
int pos = 0;
int re = 0;
for(int i=0;i<sum&&pos<n;i++)
{
while(pos<k[i].st)
{
if(pos==n)
{
break;
}
pos++;
re++;
}
while(pos<=k[i].en)
{
if(pos==n)
{
break;
}
pos++;
}
//cout << pos << "***" << endl;
}
re += n - pos;
printf("%d\n",re);
//cout << pos << endl;
//cout << sum << "**" << endl;
}
return 0;
}
最后一题,最后1h+,直接睡着了,由于前两题做得太慢了,已经估计到了降分的悲剧,最后一题其实也是可做的,然而作息问题啊,最后有了思路,然而似乎写出了点bug没来得及交,看看吧
C. Pride
思路:这题一开始很难找到思绪,但其实这题的点就在,只要找到一个能最快使数组中出现1的方案即可,剩下的就是让这个1遍历遍数组就好了
一开始想的是,两个数的最大公约数为1,则可以在1的代价完成变换;如果两个最大公约数的最大公约数为1,则可以以3的代价变换,如此迭代把自己搞晕了
其实,这题可以直接寻找最少多少相邻的数最大公约数为1,来一个O(N^2)的暴力就解决了,根据数据范围想方案,所有想投机取巧的方法都用暴力代替
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 2020;
int a[maxn],g[maxn];
int gcd(int a, int b)
{
return b == 0 ? a : gcd(b, a % b);
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int sum = 0;
/*bool s1 = false;
bool s2 = false;*/
int s = 0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
g[i] = a[i];
if(a[i]>1)
{
sum++;
}
/*if(i>0)
{
g[i] = gcd(a[i],a[i-1]);
}*/
}
//cout << sum << "*" << endl;
//cout << s1 << "**" << s2 << endl;
if(sum==n)
{
/*if(s1);
else if(s2)
{
sum ++;
}
else
{
sum = -1;
}*/
for(s=1;s<n;s++)
{
int pos = n-1;
for(;pos>=s;pos--)
{
g[pos] = gcd(g[pos-1],a[pos]);
if(g[pos] == 1)
{
break;
}
}
if(pos >= s)
{
break;
}
}
if(s<n)
{
sum += s - 1;
}
else
{
sum = -1;
}
}
printf("%d\n",sum);
}
return 0;
}
这场实属可惜啊,题目完全可做,其实也算给自己敲一个警钟了吧,加油