hdu 4365 Palindrome graph

第七次比赛中最水的一道题之一,当场没做出来。思路堵塞。看完题解后还是不解。后来baidu了别人的做法总算茅塞顿开了。

题意照旧不解释,注意数据范围和矩阵的起始为0.

根据题意我们知道,矩阵必须对角线对称 + 十字对称(就是矩阵纵向横向的中线对称)。

所以,只要填充了矩阵的四分之一 又 一半的格子后,就可以通过各种对称变换把矩阵弄出来。


自己写的时候把其他象限变换的过程弄成超级大模拟…后来扫了一眼标程,6行足矣……

下面第一个是精简的……

第二个是保留了当初大模拟的数据…用以自愧

#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <cstdlib>
#include <cmath>
using namespace std;
const int maxx = 10010;
long long power(long long a, int k,int m)
{
    long long b = 1;
    while(k>=1)
    {
        if(k%2==1)  b = b*a%m;
        a = a*a%m;
        k = k/2;
    }
    return b;
}

int main()
{
    int n,m,k;
    while(scanf("%d %d %d",&n,&m,&k)!=EOF)
    {
        map<int,bool> q;
        for(int i=1;i<=m;i++)
        {
            int x,y;
            scanf("%d %d",&x,&y);
            if(x>n-1-x) x=n-1-x;
            if(y>n-1-y) y=n-1-y;
            if(y<x)
            {
                int tem;
                tem = y;
                y = x;
                x = tem;
            }
            q[(x-1)*n+y] = true;
        }
        int N = (((n+1)/2 + 1)*((n+1)/2))/2;
        int M = N - q.size();
        long long ans = power(k,M,100000007);
        printf("%I64d\n",ans);
    }
    return 0;
}



/**********************************豪华分割线************************************************豪华分割线***************************************/



#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <cstdlib>
#include <cmath>
using namespace std;
const int maxx = 10010;
//struct po
//{
//    int x,y;
//}point[maxx];
//
//void change2(po& Get, double xx, double yy)
//{
//    Get.y = yy - fabs((double)Get.y-yy);
//}
//void change3(po &Get, double xx, double yy)
//{
//    Get.x = xx - fabs((double)Get.x-xx);
//}
//void change(po& Get, double xx, double yy)
//{
//    if(Get.x<=xx && Get.y>=yy)//第二象限
//        change2(Get,xx,yy);
//    else if(Get.x>=xx && Get.y<=yy)//第三象限
//        change3(Get,xx,yy);
//    else if(Get.x>=xx && Get.y>=yy)//第四象限
//    {
//        change2(Get,xx,yy);
//        change3(Get,xx,yy);
//    }
//}
//
//void change4(po &Get, double xx, double yy)
//{
//    int tem;
//    tem = Get.x;
//    Get.x = Get.y;
//    Get.y = tem;
//}
long long power(long long a, int k,int m)
{
    long long b = 1;
    while(k>=1)
    {
        if(k%2==1)  b = b*a%m;
        a = a*a%m;
        k = k/2;
    }
    return b;
}

int main()
{
//    freopen("1006.txt","r",stdin);
//    freopen("data.in","r",stdin);
//    freopen("out.txt","w",stdout);
    int n,m,k;
    while(scanf("%d %d %d",&n,&m,&k)!=EOF)
    {
        map<int,bool> q;
//        double xx = (n+1)/2.0;
//        int yy = (n+1)/2.0;
        for(int i=1;i<=m;i++)
        {
            int x,y;
            scanf("%d %d",&x,&y);
            if(x>n-1-x) x=n-1-x;
            if(y>n-1-y) y=n-1-y;
            if(y<x)
            {
                int tem;
                tem = y;
                y = x;
                x = tem;
            }
//            change(point[i],xx,xx);
//            change4(point[i],yy,yy);
            q[(x-1)*n+y] = true;
        }
        int N = (((n+1)/2 + 1)*((n+1)/2))/2;
        int M = N - q.size();
        long long ans = power(k,M,100000007);
        printf("%I64d\n",ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值