HDU-4436-str2int

本文介绍了一种使用后缀数组解决特定字符串问题的方法,该问题要求计算给定字符串能形成的不同数字之和。文章提供了详细的算法实现,并通过两个辅助数组进行优化,确保高效的计算过程。

这个题要求求出所给字符串所能形成的不同的数字的和.比较经典的后缀数组题,最开始一直TLE,后来推了公式做的~用了2个辅助数组.

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=300000;
int n,m,r[maxn],wa[maxn],wb[maxn],wv[maxn],wu[maxn],height[maxn],rank[maxn],sa[maxn],group[maxn],sum[maxn],vala[maxn],valb[maxn],moda[maxn],modb[maxn];
char str[maxn];
void Init()
{
    for(int i=2;i<maxn;i++)
	moda[i]=((moda[i-1]+1)*10)%2012;
}
int cmp(int *r,int a,int b,int l)
{
    return r[a]==r[b]&&r[a+l]==r[b+l];
}
void da(int n,int m)
{
    int i,j,p,*x=wa,*y=wb,*t;
    for(i=0;i<m;i++)
	wu[i]=0;
    for(i=0;i<n;i++)
	wu[x[i]=r[i]]++;
    for(i=1;i<m;i++)
	wu[i]+=wu[i-1];
    for(i=n-1;i>=0;i--)
	sa[--wu[x[i]]]=i;
    for(j=1,p=1;p<n;j*=2,m=p)
    {
	for(p=0,i=n-j;i<n;i++)
	    y[p++]=i;
	for(i=0;i<n;i++)
	    if(sa[i]>=j)
		y[p++]=sa[i]-j;
	for(i=0;i<n;i++)
	    wv[i]=x[y[i]];
	for(i=0;i<m;i++)
	    wu[i]=0;
	for(i=0;i<n;i++)
	    wu[wv[i]]++;
	for(i=1;i<m;i++)
	    wu[i]+=wu[i-1];
	for(i=n-1;i>=0;i--)
	    sa[--wu[wv[i]]]=y[i];
	for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
	    x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
    }
}
void calheight(int n)
{
    int i,j,k=0;
    for(i=1;i<=n;i++)
	rank[sa[i]]=i;
    for(i=0;i<n;height[rank[i++]]=k)
	for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);
}
int GetNum(int l,int r)
{
    int ans=valb[r+1]-valb[l]-(vala[l]*moda[r-l+2])%2012;
    return ans%2012;
}
int main()
{
    Init();
    while(scanf("%d",&m)!=EOF)
    {
	n=0;
	memset(group,0,sizeof(group));
	memset(vala,0,sizeof(vala));
	memset(sa,0,sizeof(sa));
	memset(rank,0,sizeof(rank));
	memset(sum,0,sizeof(sum));
	int pos=200;
	for(int i=1;i<=m;i++)
	{
	    scanf("%s",str);
	    int len=strlen(str);
	    for(int j=0;j<len;j++)
	    {
		r[n]=str[j];
		group[n]=i;
		vala[n+1]=(vala[n]*10+(str[j]-'0'))%2012;
		valb[n+1]=(valb[n]+vala[n+1])%2012;
		n++;
	    }
	    r[n]=pos++;
	    vala[n+1]=valb[n+1]=0;
	    group[n++]=0;
	    sum[i]=sum[i-1]+len+1;
	}
	r[n]=0;
	group[n]=0;
	da(n+1,11000);
	calheight(n);
	int ans=0;
	for(int i=1;i<=n;i++)
	{
	    if(group[sa[i]]==0||r[sa[i]]=='0')
		continue;
	    if(sa[i]+height[i]-1==sum[group[sa[i]]]-2)
		continue;
	    int ita=GetNum(sa[i],sum[group[sa[i]]]-2)%2012;
	    if(ita<0)
		ita+=2012;
	    ans=(ans+ita)%2012;
	    if(height[i])
	    {
		int itb=GetNum(sa[i],sa[i]+height[i]-1)%2012;
		if(itb<0)
		    itb+=2012;
		ans=(ans-itb)%2012;
	    }
	    if(ans<0)
		ans+=2012;
	}
	printf("%d\n",ans%2012);
    }
    return 0;
}


static void parse_gprmc(nmea_msg *gps, const char *buf) { const char *p = strstr(buf, "GPRMC"); if (!p) return; uint8_t pos; uint8_t dx; // UTC时间 pos = nmea_comma_pos((const uint8_t *)p, 1); if (pos != 0xFF) { uint32_t time = nmea_str2num((const uint8_t *)(p + pos), &dx); gps->utc.hour = time / 10000; gps->utc.min = (time % 10000) / 100; gps->utc.sec = time % 100; } // 状态检查 (A=有效, V=无效) pos = nmea_comma_pos((const uint8_t *)p, 2); if (pos != 0xFF && *(p + pos) == 'V') { gps->fixmode = 0; // 无效定位 return; } // 纬度 pos = nmea_comma_pos((const uint8_t *)p, 3); if (pos != 0xFF) { float lat_val = nmea_str2num((const uint8_t *)(p + pos), &dx) / 100.0f; int deg = (int)(lat_val) / 100; float min = lat_val - deg * 100; gps->latitude = deg + min / 60.0f; } // 纬度半球 pos = nmea_comma_pos((const uint8_t *)p, 4); if (pos != 0xFF) gps->nshemi = *(p + pos); // 经度 pos = nmea_comma_pos((const uint8_t *)p, 5); if (pos != 0xFF) { float lon_val = nmea_str2num((const uint8_t *)(p + pos), &dx) / 100.0f; int deg = (int)(lon_val) / 100; float min = lon_val - deg * 100; gps->longitude = deg + min / 60.0f; } // 经度半球 pos = nmea_comma_pos((const uint8_t *)p, 6); if (pos != 0xFF) gps->ewhemi = *(p + pos); } // 完整GPGGA解析 static void parse_gpgga(nmea_msg *gps, const char *buf) { const char *p = strstr(buf, "GPGGA"); if (!p) return; uint8_t pos; uint8_t dx; // UTC时间 pos = nmea_comma_pos((const uint8_t *)p, 1); if (pos != 0xFF) { uint32_t time = nmea_str2num((const uint8_t *)(p + pos), &dx); gps->utc.hour = time / 10000; gps->utc.min = (time % 10000) / 100; gps->utc.sec = time % 100; } // 纬度 pos = nmea_comma_pos((const uint8_t *)p, 2); if (pos != 0xFF) { float lat_val = nmea_str2num((const uint8_t *)(p + pos), &dx) / 100.0f; int deg = (int)(lat_val) / 100; float min = lat_val - deg * 100; gps->latitude = deg + min / 60.0f; } // 纬度半球 pos = nmea_comma_pos((const uint8_t *)p, 3); if (pos != 0xFF) gps->nshemi = *(p + pos); // 经度 pos = nmea_comma_pos((const uint8_t *)p, 4); if (pos != 0xFF) { float lon_val = nmea_str2num((const uint8_t *)(p + pos), &dx) / 100.0f; int deg = (int)(lon_val) / 100; float min = lon_val - deg * 100; gps->longitude = deg + min / 60.0f; } // 经度半球 pos = nmea_comma_pos((const uint8_t *)p, 5); if (pos != 0xFF) gps->ewhemi = *(p + pos); // 定位质量 pos = nmea_comma_pos((const uint8_t *)p, 6); if (pos != 0xFF) gps->fixmode = nmea_str2num((const uint8_t *)(p + pos), NULL); // 卫星数 pos = nmea_comma_pos((const uint8_t *)p, 7); if (pos != 0xFF) gps->posslnum = nmea_str2num((const uint8_t *)(p + pos), NULL); // 海拔高度 pos = nmea_comma_pos((const uint8_t *)p, 9); if (pos != 0xFF) gps->altitude = nmea_str2num((const uint8_t *)(p + pos), &dx) / 10.0f; } // 主解析函数 void gps_parse_nmea(nmea_msg *gps, const char *buf) { // 校验和验证 const char *end = strchr(buf, '*'); if (end) { uint8_t calc_check = nmea_str2num(buf); uint8_t recv_check = strtoul(end + 1, NULL, 16); if (calc_check != recv_check) { return; // 校验失败 } } if (strstr(buf, "GPRMC")) parse_gprmc(gps, buf); else if (strstr(buf, "GPGGA")) parse_gpgga(gps, buf); } // 显示数据 void gps_show_data(const nmea_msg *gps) { if (gps->fixmode == 0) { printf("No valid GPS fix\n"); return; } printf("Longitude: %.6f° %c\n", gps->longitude, gps->ewhemi); printf("Latitude: %.6f° %c\n", gps->latitude, gps->nshemi); printf("Altitude: %.1f meters\n", gps->altitude); printf("UTC Time: %02d:%02d:%02d\n", gps->utc.hour, gps->utc.min, gps->utc.sec); printf("Satellites: %d\n", gps->posslnum); printf("Fix mode: %s\n", gps->fixmode == 1 ? "GPS" : gps->fixmode == 2 ? "DGPS" : "Unknown"); } 修过后该处显示以下错误如何修改[OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c: In function 'gps_parse_nmea': [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:174:43: warning: pointer targets in passing argument 1 of 'nmea_str2num' differ in signedness [-Wpointer-sign] [OHOS ERROR] uint8_t calc_check = nmea_str2num(buf); [OHOS ERROR] ^~~ [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:27:5: note: expected 'const uint8_t * {aka const unsigned char *}' but argument is of type 'const char *' [OHOS ERROR] int nmea_str2num(const uint8_t *buf, uint8_t *dx) { [OHOS ERROR] ^~~~~~~~~~~~ [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:174:30: error: too few arguments to function 'nmea_str2num' [OHOS ERROR] uint8_t calc_check = nmea_str2num(buf); [OHOS ERROR] ^~~~~~~~~~~~ [OHOS ERROR] ../../../vendor/pzkj/pz_hi3861/common/bsp/src/bsp_gps.c:27:5: note: declared here [OHOS ERROR] int nmea_str2num(const uint8_t *buf, uint8_t *dx) { [OHOS ERROR] ^~~~~~~~~~~~ [OHOS ERROR] you can check build log in D:\hi3861\hi3861_hdu_iot_application\src\out\hispark_pegasus\wifiiot_hispark_pegasus\build.log [OHOS ERROR] command: "D:\hi3861\hi3861_hdu_iot_application\src\prebuilts\build-tools\win64-x64\bin\ninja.exe -w dupbuild=warn -C D:\hi3861\hi3861_hdu_iot_application\src\out\hispark_pegasus\wifiiot_hispark_pegasus" failed [OHOS ERROR] return code: 1 [OHOS ERROR] execution path: D:\hi3861\hi3861_hdu_iot_application\src scons: *** [src\out\hispark_pegasus\wifiiot_hispark_pegasus\target.elf] Error -1
07-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值