noip模拟赛 毁灭

Posted zbtrs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了noip模拟赛 毁灭相关的知识,希望对你有一定的参考价值。

题目描述

YJC决定对入侵C国的W国军队发动毁灭性打击。将C国看成一个平面直角坐标系,W国一共有n^2个人进入了C国境内,在每一个(x,y)(1≤x,y≤n)上都有恰好一个W国人。YJC决定使用m颗核导弹,每一颗核导弹将杀死某个圆内所有的W国人,恰好在圆上也会被杀死。现在YJC想知道,在这一轮核打击之后,还有多少个W国人在C国境内。

输入输出格式

输入格式:

 

第一行包含两个整数n和m,意思如题所示。

接下来m行每行三个整数x,y和r,表示以(x,y)为圆心,r为半径的圆圆内和圆上的W国人被全部杀死。

 

输出格式:

 

一行,包含一个整数,表示幸存的W国人个数。

 

输入输出样例

输入样例#1:
3 2
2 2 1
1 1 2
输出样例#1:
1

说明

第一枚导弹杀死了(1,2)、(2,1)、(2,2)、(2,3)、(3,2)上的W国人,第二枚导弹杀死了(1,1)、(1,2)、(1,3)、(2,1)、(2,2)、(3,1)上的W国人,只剩下(3,3)上的W国人没有被杀死。

对于50%的数据,满足n,m≤50。

对于100%的数据,满足1≤x,y≤n≤5000,0≤r≤n,1≤m≤5000。

分析:一个暴力的想法是枚举每个点和每个核弹,计算点到圆心的距离与半径的关系来看能否被覆盖到,这种做法只有50分.

      考虑一下如何优化枚举,之前是枚举每个点对应每个核弹,现在看每个核弹能够覆盖到的点,将圆分层考虑,利用勾股定理算出每一层的左端点和有端点,然后区间覆盖,最后统计每个点被覆盖了几次,将没有被覆盖的点的个数加起来就是答案了.

      如果还是一个一个点的覆盖那么复杂度也变不了多少,但是我们最后只需要求每一个点的值,而且对应的是区间修改,那么我们可以用差分来做,最后求一下前缀和就可以了.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

char s[15];
int a1[7], a2[7],cnt;
bool flag = false;

void lturn()
{
    int t = a1[5];
    a1[5] = a1[4];
    a1[4] = a1[2];
    a1[2] = a1[3];
    a1[3] = t;
}

void uturn()
{
    int t = a1[1];
    a1[1] = a1[2];
    a1[2] = a1[6];
    a1[6] = a1[5];
    a1[5] = t;
}

bool check()
{
    for (int i = 1; i <= 6; i++)
        if (a1[i] != a2[i])
            return false;
    return true;
}

int main()
{
    while (scanf("%s", s + 1))
    {
        for (int i = 1; i <= 6; i++)
            a1[i] = s[i] - b;
        for (int i = 7; i <= 12; i++)
            a2[i - 6] = s[i] - b;
        flag = 0;
        cnt = 0;
        while (1)
        {
            if (check())
            {
                flag = 1;
                break;
            }
            else
            {
                for (int i = 1; i <= 8; i++)
                {
                    lturn();
                    for (int j = 1; j <= 8; j++)
                    {
                        uturn();
                        cnt++;
                        if (check())
                        {
                            flag = 1;
                            break;
                        }
                    }
                    if (flag)
                        break;
                }
            }
            if (flag)
                break;
            if (cnt > 400)
                break;
        }
        if (flag)
            printf("TRUE\n");
        else
            printf("FALSE\n");
    }

    return 0;
}

 

以上是关于noip模拟赛 毁灭的主要内容,如果未能解决你的问题,请参考以下文章

9.26模拟赛

noip模拟赛 写代码

NOIp模拟赛binary

NOIP模拟赛16

NOIp模拟赛value

8.3模拟赛总结