0
点赞
收藏
分享

微信扫一扫

AtCoder Regular Contest 068


 

C - X: Yet Another Die Game

Time Limit: 2 sec / Memory Limit: 256 MB

Score : 300300 points

Problem Statement

Snuke has decided to play with a six-sided die. Each of its six sides shows an integer 11 through 66, and two numbers on opposite sides always add up to 77.

Snuke will first put the die on the table with an arbitrary side facing upward, then repeatedly perform the following operation:

  • Operation: Rotate the die 90°90° toward one of the following directions: left, right, front (the die will come closer) and back (the die will go farther). Then, obtain yy points where yy is the number written in the side facing upward.

For example, let us consider the situation where the side showing 11 faces upward, the near side shows 55 and the right side shows 44, as illustrated in the figure. If the die is rotated toward the right as shown in the figure, the side showing 33 will face upward. Besides, the side showing 44 will face upward if the die is rotated toward the left, the side showing 22 will face upward if the die is rotated toward the front, and the side showing 55 will face upward if the die is rotated toward the back.

AtCoder Regular Contest 068_sed

Find the minimum number of operation Snuke needs to perform in order to score at least xx points in total.

Constraints

  • 1≦x≦10151≦x≦1015
  • xx is an integer.

Input

The input is given from Standard Input in the following format:


xx


Output

Print the answer.

Sample Input 1 Copy

Copy


7


Sample Output 1 Copy

Copy


2


Sample Input 2 Copy

Copy


149696127901


Sample Output 2 Copy

Copy


27217477801


 

题意:

一个色子,前后左右的翻转,问翻转几次,可以到达x(开始位置任意)。

分析:

6 5 6 5的翻即可

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
#define INF 0x7fffffff
#define PI acos(-1.0)
#define MOD 2520
#define E 1e-12
#define ll long long
using namespace std;
#define N 1500
int a[N];
int main()
{
ll n;
scanf("%lld",&n);
if(n<=6)
{
cout<<1<<endl;
}
else
{
ll ans=0;
ll x=n/11;
ll y=n%11;
ans+=2*x;
if(y<=6&&y>=1)
{
ans++;
}
else if(y>6)
{
ans+=2;
}
cout<<ans<<endl;

}

return 0;
}

D - Card Eater

Time Limit: 2 sec / Memory Limit: 256 MB

Score : 400400 points

Problem Statement

Snuke has decided to play a game using cards. He has a deck consisting of NN cards. On the ii-th card from the top, an integer AiAi is written.

He will perform the operation described below zero or more times, so that the values written on the remaining cards will be pairwise distinct. Find the maximum possible number of remaining cards. Here, NN is odd, which guarantees that at least one card can be kept.

Operation: Take out three arbitrary cards from the deck. Among those three cards, eat two: one with the largest value, and another with the smallest value. Then, return the remaining one card to the deck.

Constraints

  • 3≦N≦1053≦N≦105
  • NN is odd.
  • 1≦Ai≦1051≦Ai≦105
  • AiAi is an integer.

Input

The input is given from Standard Input in the following format:


NN A1A1 A2A2 A3A3 ... ANAN


Output

Print the answer.

Sample Input 1 Copy

Copy


5 1 2 1 3 7


Sample Output 1 Copy

Copy


3


One optimal solution is to perform the operation once, taking out two cards with 11 and one card with 22. One card with 11 and another with 22 will be eaten, and the remaining card with 11 will be returned to deck. Then, the values written on the remaining cards in the deck will be pairwise distinct: 11, 33 and 77.

Sample Input 2 Copy

Copy

15
1 3 5 2 1 3 2 8 8 6 2 6 11 1 1


Sample Output 2 Copy

Copy


7


题意:

n个数,删除方式:任意选三个数,删除这三个数的最小的数和最大的数,中间的数放回。保证最后的数没有重复的,问最多可以留下的数的数量。

分析:

贪心思想,我们选三个数的:(重复的数)中最小和最大的拼在一起,随便选一个中间的数就行(肯定有最小和最大都至少是两个), 然后如果只剩下自己重复需要自己选出来三个,直到剩下两个。这两个的就需要拉一个垫背的。

#include <bits/stdc++.h>
using namespace std;
#define INF 0x7fffffff
#define PI acos(-1.0)
#define MOD 2520
#define E 1e-12
#define ll long long
using namespace std;
#define N 150000
int a[N];
int num[N];
int main()
{
int n;
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
num[a[i]]++;
}
sort(a+1,a+n+1);
int r=n;
int ans=0;
for(int i=1; i<=n; i++)
{
if(num[a[i]]>=2)
{
if(r<i)
{
ans+=(num[a[i]]-1)*2;
}
else
{
while(num[a[i]]>=2)
{
while(num[a[r]]>=2)
{
num[a[r]]--;
num[a[i]]--;
ans+=2;
if(num[a[i]]==1)
break;
}
r--;
if(r<i)
{
ans+=(num[a[i]]-1)*2;
break;
}
}
}

}
}
cout<<n-ans<<endl;


return 0;
}

E - Snuke Line

Time Limit: 2 sec / Memory Limit: 256 MB

Score : 700700 points

Problem Statement

Snuke has decided to play a game, where the player runs a railway company. There are M+1M+1 stations on Snuke Line, numbered 00 through MM. A train on Snuke Line stops at station 00 and every dd-th station thereafter, where dd is a predetermined constant for each train. For example, if d=3d=3, the train stops at station 00, 33, 66, 99, and so forth.

There are NN kinds of souvenirs sold in areas around Snuke Line. The ii-th kind of souvenirs can be purchased when the train stops at one of the following stations: stations lili, li+1li+1, li+2li+2, ......, riri.

There are MM values of dd, the interval between two stops, for trains on Snuke Line: 11, 22, 33, ......, MM. For each of these MM values, find the number of the kinds of souvenirs that can be purchased if one takes a train with that value of dd at station 00. Here, assume that it is not allowed to change trains.

Constraints

  • 1≦N≦3×1051≦N≦3×105
  • 1≦M≦1051≦M≦105
  • 1≦li≦ri≦M1≦li≦ri≦M

Input

The input is given from Standard Input in the following format:


NN MM l1l1 r1r1 :: lNlN rNrN


Output

Print the answer in MM lines. The ii-th line should contain the maximum number of the kinds of souvenirs that can be purchased if one takes a train stopping every ii-th station.

Sample Input 1 Copy

Copy


3 3 1 2 2 3 3 3


Sample Output 1 Copy

Copy


3 2 2


  • If one takes a train stopping every station, three kinds of souvenirs can be purchased: kind 11, 22 and 33.
  • If one takes a train stopping every second station, two kinds of souvenirs can be purchased: kind 11 and 22.
  • If one takes a train stopping every third station, two kinds of souvenirs can be purchased: kind 22 and 33.

Sample Input 2 Copy

Copy


7 9 1 7 5 9 5 7 5 9 1 1 6 8 3 4


Sample Output 2 Copy

Copy


7 6 6 5 4 5 5 3 2


题意:

 M+1 个车站(0 ~ M 编号)。 N 种商品,第 i 种只在编号 [li,ri] 的车站出售。

求对于每一个 d,从 0 出发,只会在 d 的倍数车站停车。对于 d 从 1 到 M 的列车,求最多能买到多少种商品。

分析:

我们需要思想:

我们来考虑对于每一个d,会有多少种商品无法购买。

车子停下来点集:(0,d,2d,3d,.....kd)(kd<=m)。

我们可以知道无法购买的商品i,必定满足其(li,ri)在上述点集某两个相邻点之间,即可以购买的商品,必然会跨过若干个点。

即得到核心性质:对于d,所有ri-li>=d的i都是可以购买的。

所有我们把所有商品按ri-li的大小排序,对于ri-li>=d的直接加上;其他商品,由于ri-li<d,它们最多跨过一个点,则我们只需要枚举跨过某个点的商品个数总和,树状数组实现前缀和。

#include <bits/stdc++.h>
using namespace std;
#define INF 0x7fffffff
#define PI acos(-1.0)
#define MOD 2520
#define E 1e-12
using namespace std;
typedef long long ll;
const int MAXN=500000+5;//最大元素个数
int n,m;//元素个数
int c[MAXN];//c[i]==A[i]+A[i-1]+...+A[i-lowbit(i)+1]
//返回i的二进制最右边1的值
int lowbit(int i)
{
return i&(-i);
}
//返回A[1]+...A[i]的和
int sum(int x)
{
int sum = 0;
while(x)
{
sum += c[x];
x -= lowbit(x);
}
return sum;
}
//令A[i] += val
void add(int x, int val)
{

while(x <= n) //注意这里的n,是树状数组维护的长度
{
c[x] += val;
x += lowbit(x);
}
}
struct node
{
int l,r;
}a[MAXN];
bool cmp(node x,node y)
{
return x.r-x.l<y.r-y.l;
}

int main()
{

while(scanf("%d%d",&m,&n)!=-1)
{
memset(c,0,sizeof(c));
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a[i].l,&a[i].r);
}
sort(a+1,a+m+1,cmp);

int j=0;
for(int d=1;d<=n;d++)
{
int temp=0;
for(int i=d;i<=n;i+=d)//计算以前区间跨过一个点的个数
{
temp+=sum(i);
}
//m-j表示ri-li>=d的商品数量
printf("%d\n",temp+m-j);

while(j<m&&a[j+1].r-a[j+1].l<=d)//最多可能跨过一个点的商品数量记录到树状数组上
{
add(a[j+1].l,1);
add(a[j+1].r+1,-1);
j++;
}

}
}
return 0;
}

 

举报

相关推荐

0 条评论