Best ACMer Solves the Hardest Problem 【Gym - 101955G】【暴力枚举】

题目链接

题目大意

有一个的矩阵,n个点,每个点有一个权值,m次操作,有四种类型
1.增加一个点在x,y,权值为w
2.删除在x,y的点
3.在(x,y)距离为k的点都增加w的权值
4(x,y)距离k的点的权值和

解题思路

因为k只有1e7所以暴力枚举出来所有的可能的组合,然后暴力
memset会超时,所以把点存一下,最后清零

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<set>
using namespace std;
vector<pair<int,int> >v[10000007],kk;
set<pair<int,int> >s;
const int N=6003;
long long last;
int e[N][N];
int nex[4][2]={{1,1},{-1,-1},{-1,1},{1,-1}};

void init()
{
    for(int i=0;i<=6000;i++)
    {
        for(int j=0;j<=6000;j++)
        {
            if((i*i+j*j)<=10000000)
            {
            v[i*i+j*j].push_back(make_pair(i,j));
            }
            else
                break;
        }
    }
}

void F1(int x,int y,int k)
{
    s.clear();
    long long ans=0;
    int l=v[k].size();
    //printf("*%d\n",l);
    for(int i=0;i<l;i++)
    {
        int xx=v[k][i].first;
        int yy=v[k][i].second;
        for(int j=0;j<4;j++)
        {
            int tx=x+xx*nex[j][0];
            int ty=y+yy*nex[j][1];
            if(tx<=0||ty<=0||tx>6000||ty>6000)
                continue;
            s.insert(make_pair(tx,ty));
        }
    }
    auto it=s.begin();
    while(it!=s.end())
    {
        pair<int,int> a;
        a=*it;
        int tx=a.first;
        int ty=a.second;
       // printf("%d %d %d\n",tx,ty,e[tx][ty]);
        ans+=e[tx][ty];
        it++;
    }
    last=ans;
    printf("%lld\n",ans);
}

void F(int x,int y,int z,int w)
{
    s.clear();
    int l=v[z].size();
   // printf("*%d\n",l);
    for(int i=0;i<l;i++)
    {
        int xx=v[z][i].first;
        int yy=v[z][i].second;
        for(int j=0;j<4;j++)
        {
            int tx=x+xx*nex[j][0];
            int ty=y+yy*nex[j][1];
            if(tx<=0||ty<=0||tx>6000||ty>6000)
                continue;
            if(tx==x&&ty==y)
                continue;
            s.insert(make_pair(tx,ty));
        }
    }
    auto it=s.begin();
    while(it!=s.end())
    {
        pair<int,int> a;
        a=*it;
        int tx=a.first;
        int ty=a.second;
        //printf("%d %d %d\n",tx,ty,e[tx][ty]);
        if(e[tx][ty])
        e[tx][ty]+=w;
        it++;
    }
}
int main()
{
    init();
    //printf("%d\n",v[1].size());
    int T,p=1;
    int n,m;
    int x,y,z,w;
    scanf("%d",&T);
    while(T--)
    {
        kk.clear();
        last=0;
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d %d %d",&x,&y,&z);
            e[x][y]=z;
            kk.push_back(make_pair(x,y));
        }
        printf("Case #%d:\n",p++);
        while(m--)
        {
            int k;
            scanf("%d",&k);
            if(k==1)
            {
                scanf("%d %d %d",&x,&y,&z);
                x=(x+last)%6000+1;
                y=(y+last)%6000+1;
                e[x][y]=z;
                kk.push_back(make_pair(x,y));
            }
            else if(k==2)
            {
                scanf("%d %d",&x,&y);
                x=(x+last)%6000+1;
                y=(y+last)%6000+1;
                e[x][y]=0;
            }
            else if(k==3)
            {
                scanf("%d %d %d %d",&x,&y,&z,&w);
                x=(x+last)%6000+1;
                y=(y+last)%6000+1;
                if(z==0)
                {
                    if(e[x][y])
                        e[x][y]+=w;
                }
                else
                F(x,y,z,w);
            }
            else
            {
                scanf("%d %d %d",&x,&y,&z);
                x=(x+last)%6000+1;
                y=(y+last)%6000+1;
                if(z==0)
                {
                        printf("%d\n",e[x][y]);
                    last=e[x][y];
                }
                else
                F1(x,y,z);
            }
        }
        int l=kk.size();
        for(int i=0;i<l;i++)
		{
         e[kk[i].first][kk[i].second]=0;
		}
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值