CodeForces - 202C Clear Symmetry (预处理模拟+找规律)

本文详细介绍了如何解决CodeForces上的202C问题——Clear Symmetry。通过预处理数据并寻找模式,我们可以找到有效的解决方案。文章深入探讨了预处理技术在解决算法竞赛问题中的应用,并提供了详细的解题思路和步骤。


Consider some square matrix A with side n consisting of zeros and ones. There aren rows numbered from 1 to n from top to bottom and n columns numbered from 1 to nfrom left to right in this matrix. We'll denote the element of the matrix which is located at the intersection of the i-row and the j-th column as Ai, j.

Let's call matrix A clear if no two cells containing ones have a common side.

Let's call matrix A symmetrical if it matches the matrices formed from it by a horizontal and/or a vertical reflection. Formally, for each pair (i, j) (1 ≤ i, j ≤ n) both of the following conditions must be met: Ai, j = An - i + 1, j and Ai, j = Ai, n - j + 1.

Let's define the sharpness of matrix A as the number of ones in it.

Given integer x, your task is to find the smallest positive integer n such that there exists a clear symmetrical matrix A with side n and sharpness x.

Input

The only line contains a single integer x (1 ≤ x ≤ 100) — the required sharpness of the matrix.

Output

Print a single number — the sought value of n.

Example
Input
4
Output
3
Input
9
Output
5
Note

The figure below shows the matrices that correspond to the samples:



先解释一下这道题的意思啊。。他是说给你一个数,问你在他所给的规则之下,,最少需要几阶方格才能存下。

规则呢:就是说比如一个5阶的情况,刚开始他的所有空都是0。。你要尽可能多的往里面填补1。但是每当你填补一个1以后。

填补位置坐标为i,j。同时n+1-i,j和i,n+1-j也要同时变为1。当另外两个变为1以后。这三个点就可以形成一个正方形,,同理想一下第四个点要变成什么呢。。

没错,也是1。还有就是对n%4之后的结果做处理。。如果结果不为0,在判断是否pos为奇数,否 ,则+1;

如果是奇数时,再看pos -  n  >=  n-1,否,则pos += 2。变成奇数。

还有开始要通过预处理模拟一下各阶能够容纳1的个数。。再看一下x的范围<=100.所以控制其中1的个数大于100就结束就OK啦。



#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <map>
#include <sstream>
#include <queue>
#include <stack>
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a));
#define For(a,b) for(int i = a;i<b;i++)
#define LL long long
#define MAX_N 100010
using namespace std;
int x[10000];
int ma[1000][1000];
int init()
{
    mem(x,0);
    for(int i = 3; ; i++)
    {
        mem(ma,0);
        int ans = 0;
        for(int j = 1; j<=i; j++)
        {
            for(int k = 1; k<=i; k++)
            {
                if(ma[j][k]) continue;
                if(!ma[j-1][k]&&!ma[j][k-1]&&!ma[j+1][k]&&!ma[j][k+1])
                {
                    ma[j][k] = 1;
                    ans ++;
                    if(!ma[i-j][k]&&!ma[i+1-j][k-1]&&!ma[i+2-j][k]&&!ma[i+1-j][k+1])
                    {
                        if(!ma[i+1-j][k]) ans ++;
                        ma[i+1-j][k] = 1;
                        if(!ma[j-1][i+1-k]&&!ma[j][i-k]&&!ma[j+1][i+1-k]&&!ma[j][i+2-k])
                        {
                            if(!ma[j][i+1-k]) ans ++;
                            ma[j][i+1-k] = 1;
                            if(!ma[i-j][i+1-k]&&!ma[i+1-j][i-k]&&!ma[i+2-j][i+1-k]&&!ma[i+1-j][i+2-k])
                            {
                                if(!ma[i+1-j][i+1-k]) ans ++;
                                ma[i+1-j][i+1-k] = 1;
                            }
                        }
                    }
                }
            }
        }
//        if(i==5)
//            for(int p=1; p<=5; p++)
//            {
//                for(int l = 1; l<=5; l++)cout<<ma[p][l];
//                cout<<endl;
//            }
        x[i] = ans;
        if(ans >= 100) return i;
    }
}
int main()
{
    int num = init();
    int n;
//    for(int i = 3; i<=num; i++)
//    {
//        cout<<i<<' '<<x[i]<<endl;
//    }
    while(~scanf("%d",&n))
    {
        if(n == 1)
        {
            cout<<"1"<<endl;
            continue;
        }
        int pos = lower_bound(x,x+num,n)-x;
        if(n%4)
        {
            n%=4;
            if(pos%2==0) pos ++;
            else if(pos%2 && pos-n < n-1) pos += 2;
        }
        printf("%d\n",pos);
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值