constructive algorithms:Codeforces Round #654 (Div. 2):B. Magical Calendar

原题链接https://codeforces.com/problemset/problem/1371/B
在这里插入图片描述
当时没做出来www,首先英语不过关,读题读了好长时间,关键是我就干想了,对于我这种菜鸡来说,这种题光靠想是不行的,必须大量枚举简单的测试用例,找到规律然后就可以秒杀掉。
简单说一下题意:就是找到满足以下条件的图形的数量:

  1. all of the painted cells to be connected by side:任意方格必须有一条边与其他方格相邻。
  2. On this calendar, dates are written from the left cell to the right cell in a week. If a date reaches the last day of a week, the next day’s cell is the leftmost cell in the next (under) row.意思是就和我们用的日历一样,先从左到右排(起点可以是任意位置)达到最右端后便从下一行的最左端开始。
  3. Two shapes are the same if there exists a way to make them exactly overlapped using only parallel moves, parallel to the calendar’s sides.意思是通过平移可以重合的图形等效为一种
    下面详细说这道题怎么找规律
    1.先找案例的规律
    input
    5
    3 4
    3 2
    3 1
    13 7
    1010000 9999999
    output
    4
    3
    1
    28
    510049495001
    在这里插入图片描述
    通过这一族测试用例,我们首先发现随着r的增大,一开始ans是增大的,但在临界点之后ans不在变化,本例中的临界点是3,r>=3的结果是一样的
    之后我们可以推断出在临界点之后的结果是取决于n的
    可是具体的规律是什么呢?
    别急,我们再找一组规律
    在这里插入图片描述
    这次我们明显可以看出,有等差数列求和的意思,当r大于临界点后,ans=n*(n-1)/2+1;
    而在临界点之前,ans=(1+r)*r/2;
    于是代码出来了:
#include <iostream>

using namespace std;

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
    long long n,r;
    cin>>n>>r;
    cout<<min(n*(n-1)/2+1,(1+r)*r/2)<<endl;
    }

    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章