您的位置:首页 > 其它

codeforces Round #269(div2) C解题报告

2014-09-29 22:01 357 查看
C. MUH and House of Cards

time limit per test
1 second

memory limit per test
256 megabytes

input
standard input

output
standard output

Polar bears Menshykov and Uslada from the zoo of St. Petersburg and elephant Horace from the zoo of Kiev decided to build a house of cards. For that they've already found a hefty deck of n playing
cards. Let's describe the house they want to make:

The house consists of some non-zero number of floors.

Each floor consists of a non-zero number of rooms and the ceiling. A room is two cards that are leaned towards each other. The rooms are made in a row, each two adjoining rooms share a ceiling made by another card.

Each floor besides for the lowest one should contain less rooms than the floor below.

Please note that the house may end by the floor with more than one room, and in this case they also must be covered by the ceiling. Also, the number of rooms on the adjoining floors doesn't have to differ by one, the difference may be more.

While bears are practicing to put cards, Horace tries to figure out how many floors their house should consist of. The height of the house is the number of floors in it. It is possible that you can make a lot of different houses of different heights out of n cards.
It seems that the elephant cannot solve this problem and he asks you to count the number of the distinct heights of the houses that they can make usingexactly n cards.

Input

The single line contains integer n (1 ≤ n ≤ 1012)
— the number of cards.

Output

Print the number of distinct heights that the houses made of exactly n cards
can have.

Sample test(s)

input
13


output
1


input
6


output
0


Note

In the first sample you can build only these two houses (remember, you must use all the cards):



Thus, 13 cards are enough only for two floor houses, so the answer is 1.

The six cards in the second sample are not enough to build any house.

题目大意:

给N张卡片,求出可以拼出有多少不同层数的房间。必须用掉所有的卡片。

解法:

        首先我们可以观察,每一层的卡片数量是 2+3*(k-1)=3*k-1。我们假设搭建F层,则最小消耗卡片数量为 Nmin=3*(1+2+3+...+F)-F = 3*F*(F+1)/2-F; 然而实际消耗卡片数量为N=3*[F*(F+1)+x]-F; 其中X为任意自然数。不难判断出,Fmax不会超过



        我们可以枚举F,根据公式判断是否合法,合法则答案+1;

代码:

#include <cstdio>
#include <cmath>
#define LL long long

using namespace std;

LL n;

void init() {
scanf("%I64d", &n);
}

void solve() {
int ans=0;

for (LL i = 1; i <= sqrt(n); i++) {
LL tmp=n+i;

if (tmp%3 != 0)  continue;

tmp /= 3;
tmp -= i*(i+1)/2;
if (tmp >= 0)  ans++;
}

printf("%d\n", ans);
}

int main() {
init();
solve();
}

官方解题报告:

地址:http://codeforces.com/blog/entry/13986
从官方的解题报告看,我是属于 

的,还存在O(logN)的,因为其对数学特征挖掘更加深入。

        首先,我们可以采用二分查找法,来查找Fmax。因为我们只需要考虑其F得出的Nmin < N,不需要考虑是否合法,所以是呈现单调性,可以用二分,时间复杂度为 O(logN)。

在我们之前的数学特征挖掘之上,我们进一步挖掘:

        在之前的方法中,(n-sum[k])%3=0,那么n与sum同余,其中sum[k]表示建筑K层至少需要多少卡片。然而sum[k+1]=sum[k]+cal[k+1],其中cal[k+1]这个数组为cal[1]=2, cal[2]=5, cal[3]=8, cal[4]=11...。我们可以转换一下上面的式子 sum[k+1]%3 = (sum[k]+cal[k+1])%3 = (sum[k]+2)%3; 即 sum[k]%3 = (sum[k-1]+2)%3 = (sum[k-2]+1)%3,
即 sum[k]%3 =sum[k-3]%3 即, sum[k]与sum[k-3]同余,n与sum[k]同余,与sum[k-3]同余,与sum[k-6]同余......,所以每三层,必有1个合法。

我们可以先找到fmax的合法最大值(其实只需要看fmax与fmax-1与fmax-2 是否合法就够了),然后 ans=(F合法最大值+2)/3;

代码:

#include <iostream>
#include <cmath>
#define LL long long

using namespace std;

LL n;

void init() {
cin>>n;
}

LL cal(LL v) {
return(3*v*(v+1)/2-v);
}

LL getnum() {
LL l=1, r=1000000;

while (l != r) {
LL midn=ceil((l+r)/2.0);

if (cal(midn) <= n)
l=midn;
else
r=midn-1;
}

return(l);
}

void solve() {
LL fmax=getnum();

while ((n-cal(fmax))%3)  fmax--;
cout << (fmax+3-1)/3;
}

int main() {
init();
solve();
}


顺便在下面的评论中发现了一种数学方法,只需要O(1),一个公式即可。

有上种方法可得 fmin=3-n%3;

3*k*(k+1)/2-k <= n; 这里我们可以利用求根公式,求出kmax。

然后。。。ans=(kmax-kmin+3)/3;

代码:

#include <iostream>
#include <cmath>

using namespace std;

#define LL long long

LL n;

int main() {
cin >> n;

LL kmin=3-n%3;
LL d = sqrt(1+24*n);
LL kmax=(-1+d)/6;

cout << (kmax-kmin+3)/3;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces acm 数学