UVA 12520 Square Garden

https://vjudge.net/problem/UVA-12520

题意:n*n网格中染色m个格子,染色格子的最长轮廓线

贪心

将格子分为4类

1、隔一个选一个,互不相邻的格子

2、4个角上的格子

3、边界除角的格子

4、内部的格子

4类从上到下依次选

1对答案有4的贡献

2对答案无贡献

3对答案有-2的贡献

4对答案有-4的贡献

对n奇偶分类讨论

当n为奇数时,在分左上角的格子在第1类还是第2类讨论

#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
    freopen("data.txt","r",stdin);
    freopen("my.txt","w",stdout);
    long long ans1,ans2,n,sum,rest,now,tmp;
    while(scanf("%lld%lld",&n,&sum)!=EOF)
    {
        if(!n) return 0;
        if(n&1)
        {
            if(sum<=n*n>>1 || sum<=n*n/2+1)
            {
                printf("%lld\n",sum<<2);
                continue;
            }
            if(sum<=n*n/2+4) ans1=n*n/2*4;
            else
            {
                tmp=sum-4-n*n/2;
                ans1=n*n/2<<2;
                rest=n/2-1<<2;
                if(tmp<=rest) ans1-=tmp<<1;
                else
                {
                    ans1-=rest<<1;
                    tmp-=rest;
                    ans1-=tmp<<2;
                }
            }
            ans2=n*n/2+1<<2;
            now=n*n/2+1;
            rest=n/2<<2;
            if(sum-now<=rest) ans2-=sum-now<<1;
            else
            {
                ans2-=rest<<1;
                now+=rest;
                ans2-=sum-now<<2;
            }
            printf("%lld\n",max(ans1,ans2));
        }
        else
        {
            if(sum<=n*n>>1)
            {
                printf("%lld\n",sum<<2);
                continue;
            }
            if(sum<=n*n/2+2)
            {
                printf("%lld\n",n*n/2*4);
                continue;
            }
            ans1=n*n>>1<<2;
            tmp=sum-n*n/2-2;
            rest=n/2-1<<2;
            if(tmp<=rest) ans1-=tmp<<1;
            else
            {
                ans1-=rest<<1;
                tmp-=rest;
                ans1-=tmp<<2;
            }
            printf("%lld\n",ans1);
        }
    }
}

同一种思路大佬的写法就是短

#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
ll l,n,a,b,c,ans;
ll cal()
{
    if(n<=a) return n*4;
    if(n<=a+b) return a*4;
    if(n<=a+b+c) return a*4-(n-a-b)*2;
    return a*4-c*2-(n-a-b-c)*4;
}
int main()
{
    freopen("data.txt","r",stdin);
    freopen("std.txt","w",stdout);
    while(cin>>l>>n,l||n)
    {
        if(l%2==0)
        {
            a=l*l/2;
            b=2;
            c=l/2-1<<2;
            ans=cal();
        }
        else
        {
            a=l*l/2;
            b=l==1 ? 1:4;
            c=l==0 ? 0:(l-3)/2*4;
            ans=cal();
            a=l*l/2+1;
            b=0;
            c=(l-1)/2*4;
            ans=max(ans,cal());
        }
        cout<<ans<<endl;
    }
}
时间: 2024-12-24 02:02:11

UVA 12520 Square Garden的相关文章

UVA 10023 - Square root(手算平方根)

题目:UVA 10023 - Square root(手算平方根) 题目链接 题目大意:求给定的一个数的平方根. 解题思路:用二分但是这个数太大了,就超时了.看题接后发现需要用一种手算平方根的算法. 算法: 先判断这个数是不是偶数位,是的话就第一次取前面的两位数,不是的话第一次就只取前面的一位数来作为被除数.接下来就是两位两位为一节来计算. 用前一次的计算结果乘上20+一个个位数a再乘上这个a,找到最大的a使得这个式子的结果不大于被除数. 被除数减去这个结果然后再在尾巴接上那个大数的接下来两位作

UVA 11542 - Square(高斯消元)

UVA 11542 - Square 题目链接 题意:给定一些数字,保证这些数字质因子不会超过500,求这些数字中选出几个,乘积为完全平方数,问有几种选法 思路:对每个数字分解成质因子后,发现如果要是完全平方数,选出来的数字的每个质因子个数都必然要是偶数,这样每个质因子可以列出一个异或的方程,如果数字包含质因子,就是有这个未知数,然后进行高斯消元,求出自由变量的个数,每个自由变量可以选或不选,这样的情况就是(2^个数),然后在扣掉什么都不选的1种就是答案了 代码: #include <cstdi

UVA 11461 Square Numbers解题报告

Discription A square number is an integer number whose square root is also an integer. For example 1, 4, 81 are some square numbers. Given two numbers a and b you will have to find out how many square numbers are there between a and b (inclusive). In

UVA - 11542 Square (异或方程组)

Given n integers you cangenerate 2n-1 non-empty subsets from them. Determine for howmany of these subsets the product of all the integers in that is a perfectsquare. For example for the set {4,6,10,15} there are3 such subsets. {4}, {6,10,15} and {4,6

UVA - 10023 - Square root (模拟手算开方)

题目传送:UVA - 10023 思路:模拟手算开方,不想用c/c++,感觉太麻烦了,就直接用的java里的BigInteger类来写的,写了好久......Java还是得看看书呀,手算开方参考的这里 AC代码: import java.util.Scanner; import java.math.BigInteger; public class Main { static void fun(BigInteger x) { String str; str = x.toString(); str

高斯消元 UVA 11542 Square

题目传送门 题意:给n个数,选择一些数字乘积为平方数的选择方案数.训练指南题目. 分析:每一个数字分解质因数.比如4, 6, 10, 15,, , , , 令,表示选择第i个数字,那么,如果p是平方数,那么每个质因数上的指数为偶数,x1系数为2已经是偶数不考虑.可以转换为异或为0判断偶数,即奇数置为1,偶数置为0,然后n个数字m个质因数的增广矩阵消元看有几个自由变量(取0或1无所谓),答案是2^r - 1(全部都不取方案不算) #include <bits/stdc++.h> const in

UVA 11542 Square ——线性基

[题目分析] 每个数没有超过500的因子.很容易想到把每一个数表示成一个二进制的数. (0代表该质数的次数为偶数,1代表是奇数) 然后问题转化成了选取一些二进制数,使他们的异或和为0. 高斯消元,2^(自由元)即为答案,需要把空集的情况减去,所以减一. 然而发现并不需要知道哪些是自由元,所以只需要用线性基去维护即可. 然后代码就呼之欲出了. [代码] #include <cstdio> #include <cstring> #include <cmath> #inclu

UVa 356 - Square Pegs And Round Holes

题目:在一个2n*2n的网格中间画一个直径为2n-1的圆,问圆内部的格子以及和圆相交的格子个数. 分析:计算几何.分别计算出圆和每个整数横坐标的交点(xi,yi). ceil(yi)- ceil(yi-1)即为每列的相交格子个数,floor(yi)即为每列圆内格子个数. 说明:注意精度(⊙_⊙). #include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #i

UVA 1603 Square Destroyer

题意: 给定一个火柴棒拼成的方格阵,然后去掉一些火柴棒,问至少再去掉几根火柴棒能够让图中一个正方形都没有. 思路: 1. 由于题目中给定了 n 的范围,2 * n * (n + 1) <= 60 -> 所以能够保证所有的火柴用 long long的位运算表示; 2. 启发式函数 h 的计算需要考量:如果删除了某个方阵的一个边,则能够保证 h(s1) <= h(s2) + C(s1, s2),其中 C(s1, s2) = 1,h(s1) - h(s2) <= 1; 3. 各种位运算的