GCJ Round 1A 2008 Problem C. Numbers

本文提供了一种解决Google Code Jam 2008 Round 1A Problem C题目的方法,通过构造矩阵的方式进行快速幂运算,以高效地计算出答案。文章给出了完整的C++代码实现。

题目:GCJ Round 1A 2008 Problem C. Numbers

思路:构造矩阵水题


#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <vector>
#define eps (1e-10)
using namespace std;
#define mod 1000
struct Matrix
{
    int m[3][3];
}E,D;
void init()
{
    for(int i=1;i<=2;i++)
        for(int j=1;j<=2;j++)
            E.m[i][j]=(i==j);
    D.m[1][1]=3;
    D.m[1][2]=5;
    D.m[2][1]=1;
    D.m[2][2]=3;
}
Matrix Multi(Matrix A,Matrix B)
{
    Matrix ans;
    for(int i=1;i<=2;i++)
        for(int j=1;j<=2;j++)
        {
            ans.m[i][j]=0;
            for(int k=1;k<=2;k++)
                ans.m[i][j]=(ans.m[i][j]+A.m[i][k]*B.m[k][j])%mod;
        }
    return ans;
}
Matrix Pow(Matrix A,long long k)
{
    Matrix ans=E;
    while(k)
    {
        if(k&1)
        {
            k--;
            ans=Multi(ans,A);
        }
        else
        {
            k/=2;
            A=Multi(A,A);
        }
    }
    return ans;
}
int main()
{
    freopen("C-large-practice.in","r",stdin);
    freopen("C-large-practice.out","w",stdout);
    init();
    int t;
    scanf("%d",&t);
    for(int cas=1;cas<=t;cas++)
    {
        long long n;
        scanf("%I64d",&n);
        Matrix ans=Pow(D,n);
        printf("Case #%d: %03d\n",cas,((ans.m[1][1]*2-1)%mod+mod)%mod);
    }
    return 0;
}


### C语言实现WGS84与GCJ-02坐标系之间转换 为了实现在C语言中完成WGS84到GCJ-02的坐标转换,通常会采用特定的数学模型来调整经纬度数值。下面给出了一种基于已知公式的实现方式。 #### 定义辅助函数用于计算偏移量 ```c #include <math.h> #define PI 3.1415926535897932384626 double transformLat(double x, double y) { double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(fabs(x)); ret += (20.0 * sin(6.0 * x * PI) + 20.0 * sin(2.0 * x * PI)) * 2.0 / 3.0; ret += (20.0 * sin(y * PI) + 40.0 * sin(y / 3.0 * PI)) * 2.0 / 3.0; ret += (160.0 * sin(y / 12.0 * PI) + 320 * sin(y * PI / 30.0)) * 2.0 / 3.0; return ret; } double transformLon(double x, double y) { double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(fabs(x)); ret += (20.0 * sin(6.0 * x * PI) + 20.0 * sin(2.0 * x * PI)) * 2.0 / 3.0; ret += (20.0 * sin(x * PI) + 40.0 * sin(x / 3.0 * PI)) * 2.0 / 3.0; ret += (150.0 * sin(x / 12.0 * PI) + 300.0 * sin(x / 30.0 * PI)) * 2.0 / 3.0; return ret; } ``` #### 主要转换逻辑 通过上述定义的帮助函数`transformLat()` 和 `transformLon()`, 可以进一步构建完整的转换过程: ```c void wgs84ToGcj02(double wgLat, double wgLon, double* gcjLat, double* gcjLon){ if(outOfChina(wgLat, wgLon)){ *gcjLat = wgLat; *gcjLon = wgLon; return ; } double dLat = transformLat(wgLon - 105.0, wgLat - 35.0); double dLon = transformLon(wgLon - 105.0, wgLat - 35.0); double radLat = wgLat / 180.0 * PI; double magic = sin(radLat); magic = 1 - 0.00669342162296594323 * magic * magic; double sqrtMagic = sqrt(magic); dLat = (dLat * 180.0) / ((6378245 * (1 - 0.00669342162296594323)) / (magic * sqrtMagic) * PI); dLon = (dLon * 180.0) / (6378245 / sqrtMagic * cos(radLat) * PI); *gcjLat = wgLat + dLat; *gcjLon = wgLon + dLon; }[^3] bool outOfChina(double lat, double lon){ // 判断是否在中国范围内 if(lon < 72.004 || lon > 137.8347) return true; if(lat < 0.8293 || lat > 55.8271) return true; return false; } ``` 此代码片段展示了如何利用给定的纬度(`wgLat`)和经度(`wgLon`)作为输入参数,并返回对应的GCJ-02标准下的新位置[`gcjLat`,`gcjLon`]。对于不在中国境内的地点,则不做任何变换处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值