RANK:1450 Rating:1728-26=1702
A:
枚举欧元 ,算美元 求最小值就行。
枚举是一个很重要的东西,一直在想O1的做法,想多了,浪费150分数。。
//KX
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int M = 1e5+7;
#define ls o*2
#define rs o*2+1
#define pb push_back
int main()
{
ll n,d,e;
cin>>n>>d>>e;
e=e*5;
ll mi=n;
for(int i=0;i<=n;i++)
{
if(i*d>n)break;
mi=min(mi,(n-i*d)%e);
}
cout<<mi<<endl;
return 0;
}
B:直接算出boy最多多少个,girl最多多少个,然后算出共存的可能即可,吸取A题的教训,我直接枚举去算cnt,反正又不是我算。
//KX
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int M = 1e5+7;
#define ls o*2
#define rs o*2+1
#define pb push_back
int main()
{
ll b,g,n;
cin>>b>>g>>n;
ll nb=min(n,b),ng=min(n,g);
int cnt=0;
for(int i=0;i<=nb;i++)
{
if(n-i<=ng)cnt++;
}
cout<<cnt<<endl;
return 0;
}
C:首先我们知道判断括号序列合不合法常用的方法是,从左到右枚举,ans初值等于0.遇到右括号-1,遇到左括号+1,判断中间是否出现负数,出现就不能。没出现且最后刚好等于0就一定合法。
这一题移动一个,不就相当于ans大于等于-1即可。
//KX
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int M = 2e5+7;
#define ls o*2
#define rs o*2+1
#define pb push_back
char s[M];
int main()
{
int n;
cin>>n;
cin>>s;
int cnt=0;
bool flag=true;
for(int i=0;i<n;i++)
{
if(s[i]==')')
cnt--;
else cnt++;
// printf("%d\n",cnt);
if(cnt<-1)
{
flag=false;
break;
}
}
if(flag&&cnt==0)
puts("Yes");
else puts("No");
return 0;
}
D:题意没理解透,导致将近2小时做无用功。所以掉分了。。。
题目说只能往下和右走。。。我一直以为任意方向走,要根据连通性进行判断。
首先最多设置2个障碍物,堵住起点旁边那2个,然后如果起点终点不连通,则0个,否则枚举所有点当障碍物判起点终点是否联通。这个操作我想用带删除关系的并查集处理,但没做出来,不知道是不能还是我太弱了。。。希望有大神教教我/。
最后的时候我想到了dfs解法即正解。。。但是没敲完。。
其实这题很简单,只能往下右走,判设置最少障碍物能否到终点,即判是否至少有2条完全不同的路径到达终点,如果有,则要设置2个,如果只有一条,则设置1个,否则设置0个。
找路径直接能向下就向下,否则就向右,经过的点设成不可达点。跑2遍一定是尽可能不同的。
再说一下4个方向,如果4个方向这样做就错了,因为这种贪心正确的前提是必须贴着不可达的点走,2条路径尽可能背离,即第一条路径尽可能走最少的空间。所以如果4个方向,我们就判断怎样能贴着不可达点走2遍就行了。
//KX
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int M = 1e6+7;
#define ls o*2
#define rs o*2+1
#define pb push_back
vector<char>p[M];
vector<int>z[3];
char s[M];
int n,m;
bool to;
void dfs(int x,int y,int k)
{
if(to)return;
// printf("--------- %d %d\n",x,y);
if(x==n-1&&y==m-1)
{
to=true;
return ;
}
if(x>=n||y>=m||x<0||y<0)return ;
if(p[x][y]=='#')return ;
// printf("%d %d %c\n",x,y,p[x][y]);
if(!(x==0&y==0))
{
p[x][y]='#';
z[k].pb(x*m+y);
}
dfs(x,y+1,k);
dfs(x+1,y,k);
}
int mp[M];
int main()
{
/* freopen("1.in","r",stdin);
freopen("1.out","w",stdout);*/
cin>>n>>m;
for(int i=0;i<n;i++)
{
scanf("%s",s+1);
int len=strlen(s+1);
for(int j=1;j<=len;j++)
{
p[i].pb(s[j]);
}
}
dfs(0,0,1);
if(!to){
puts("0");
return 0;
}
to=false;
dfs(0,0,2);
if(!to){
puts("1");
return 0;
}
else
puts("2");
return 0;
}
E:我感觉这一题真的简单,第二天补题的时候,看懂题意,想了5分钟就出来了,可能不是在比赛,思维放松。
我们先让奇数灯泡 互相连接。然后,从左往右枚举灯泡,放其对应的另一个灯泡即可,。
为了保证从左往右能放,我们需要事先按一对灯泡直接的距离从大到小排序。
这样一定保证另一个灯泡有位置放。
比如:
3
3 3 3
这组样例
我们先连接 1 - 3 -5
然后枚举灯泡,1,发现2跟他距离要是3 ,所以在5后面接上2,再往后发现3跟4的距离也是3,由于我们往右推进,长链距离-1,但是之前接上了一个灯泡,距离又加1 .
由于刚开始距离最大是n,而且是递非增的。如果距离和长链相同,那么长链长度不变,如果距离比长链小,那么长链长度-1.这样保证始终长链长度大于距离,即一定可以构造出解。
再回到刚才样例。
1-3-5-2-4-6
这样连接即可。
//KX
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int M = 1e6+7;
#define ls o*2
#define rs o*2+1
#define pb push_back
struct node
{
int id,d;
}P[M];
bool cmp(node a,node b)
{
return a.d>b.d;
}
int l[M],r[M];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d",&P[i].d);
P[i].id=i*2-1;
}
sort(P+1,P+1+n,cmp);
for(int i=1;i<n;i++)
{
l[i]=P[i].id,r[i]=P[i+1].id;
}
int pre=r[n-1];
int cnt=n-1;
int rt=n;
for(int i=1;i<=n;i++)
{
int dnow=P[i].d;
l[++cnt]=P[i+dnow-1].id;
r[cnt]=P[i].id+1;
if(i+dnow-1==rt)
P[++rt].id=r[cnt];
}
for(int i=1;i<=cnt;i++)
{
printf("%d %d\n",l[i],r[i]);
}
return 0;
}