又是一场unrated比赛,连续熬夜打了两场unrated比赛,不过这场与上场不同,上场是个涨粉的好机会,而似乎是好久没打了,这场却险些大掉分,既然是unrated场,那么就又是题目区分度不大,导致手速成为关键,而这场一道纯暴力却卡a上了,不得不说险些成为血崩场
先来看看这个被卡的a题吧
A. ACM ICPC
思路:将六个数分两组,判断是否可以使两组总和相等
其实,由于数据范围特别小,完全可以暴力枚举, C(n,n/2)= 24,虽为O(n!)的复杂度,然而由于n特别小,轻松搞定,其实,更暴力的算法O(n^3)= 216也完全可以接受。
然而,为了使自己的算法比较优秀,我就想了更简便的方法,由于6个数分成两组,则任意三个数中,总有两个数在一组,于是C(3,2)=3
然而,万万没想到的事,数组范围的忽视使得这题这种wa,顺间将自己推向了血崩的边缘,猛然发现,赶紧追赶吧
#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[6];
int in[10100];
int main()
{
while(scanf("%d",&a[0])!=EOF)
{
/*int sum = a[0];
for(int i=1;i<6;i++)
{
scanf("%d",&a[i]);
sum += a[i];
}
bool yes = false;
if(sum%2==0)
{
if(a[0]+a[1]+a[2]==sum/2)
{
yes = true;
}
else if(a[0]+a[1]+a[3]==sum/2)
{
yes = true;
}
else if(a[0]+a[1]+a[4]==sum/2)
{
yes = true;
}
else if(a[0]+a[1]+a[5]==sum/2)
{
yes = true;
}
else if(a[0]+a[2]+a[3]==sum/2)
{
yes = true;
}
else if(a[0]+a[2]+a[4]==sum/2)
{
yes = true;
}
else if(a[0]+a[2]+a[5]==sum/2)
{
yes = true;
}
else if(a[0]+a[3]+a[4]==sum/2)
{
yes = true;
}
else if(a[0]+a[3]+a[5]==sum/2)
{
yes = true;
}
else if(a[0]+a[4]+a[5]==sum/2)
{
yes = true;
}
if(yes)
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
else
{
printf("NO\n");
}*/
memset(in,0,sizeof(in));
int sum = a[0];
in[a[0]]++;
for(int i=1;i<6;i++)
{
scanf("%d",&a[i]);
sum += a[i];
in[a[i]]++;
}
sort(a,a+6);
if(sum%2==0)
{
sum /= 2;
bool yes = false;
in[a[0]]--;
in[a[1]]--;
//cout << sum-a[0]-a[1] << " " << in[sum-a[0]-a[1]];
if(in[sum-a[0]-a[1]]>0)
{
yes = true;
//cout << "*";
}
in[a[0]]++;
in[a[1]]++;
in[a[0]]--;
in[a[2]]--;
if(in[sum-a[0]-a[2]]>0)
{
yes = true;
//cout << "**";
}
in[a[0]]++;
in[a[2]]++;
in[a[1]]--;
in[a[2]]--;
if(in[sum-a[1]-a[2]]>0)
{
yes = true;
//cout << "***";
}
in[a[1]]++;
in[a[2]]++;
if(yes)
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
else
{
printf("NO\n");
}
}
return 0;
}
B. Vlad and Cafes
思路:统计最后未被访问的房间
于是反向枚举,当枚举到n-1个房间时,最后剩余的房间就是最终结果
#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 = 2e5+10;
int a[maxn];
bool in[maxn];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
memset(in,false,sizeof(in));
int sum = 0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
if(!in[a[i]])
{
in[a[i]] = true;
sum++;
}
}
for(int i=n-1;i>=0;i--)
{
if(sum == 1)
{
break;
}
if(in[a[i]])
{
in[a[i]] = false;
sum--;
}
}
int re;
for(int i=0;i<maxn;i++)
{
if(in[i])
{
re = i;
break;
}
}
printf("%d\n",re);
}
return 0;
}
C. Petya and Catacombs
思路:求最小房间数,那就显然是个贪心策略了
对于房间,每次可以随机生成一个数,或者写上次待在这个房间的时间
那么直接贪心就好了,用一个数组记录每个时间点可被访问的情况,初始化为均不可被访问
然后遍历时间,每次遍历后,都将该时间点设置为可被访问
对于每次遍历的结果,如果可访问,即当前时间点访问该时间点的房间,于是不用开辟新房间,并将该时间设置为不可被访问
否则,即必须开辟新房间
#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 = 2e5+10;
bool last[maxn];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int sum = 1;
memset(last,false,sizeof(last));
last[0] = true;
for(int i=1;i<=n;i++)
{
int t;
scanf("%d",&t);
if(last[t])
{
last[t] = false;
}
else
{
sum++;
}
last[i] = true;
}
printf("%d\n",sum);
}
return 0;
}
后两题由于危机感,还是挺顺畅的,然而第一题有点坑了,细心啊
最后D题,实在太困了,写到睡着,也是无奈,算了,估计这段时间也没时间补这题了,暂时就这样吧
文章地址:http://blog.csdn.net/owen_q/article/details/78564459