hdu 4909 String(計數),hdu4909
題目連結:hdu 4909 String
題目大意:給定一個字串,由小寫字母組成,最多包含一個問號,問號可以表示空或者任意一個字母。問有多少個子串,字母出現的次數均為偶數。
解題思路:因為最多又26個字母,對應每個字母的奇數情況用1表示,偶數情況用0.將一個首碼串表示成一個位元。然後對於每種相同的數s,任選兩個即為一種可行子串(組合數學). 接著對於有問號的情況枚舉一下問號替代的字元,然後對於問號後面的狀態都要再加上一個該字元。這時計算個數時就要將前後分開討論了。
這題交C++,結果卡FST了,覺得很不科學,加排序複雜度才o(nlogn), 然後叫G++就過了,不過開別人好像是開了一個1<<26的數組計算個數,空間限的也太鬆了。
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef int ll;const int maxn = 20005;int n, num[maxn], s[maxn];char str[maxn];ll solve () { int tmp = num[0] = 0; for (int i = 1; i <= n; i++) { if (str[i] != '?') tmp ^= (1<<(str[i]-'a')); s[i] = num[i] = tmp; } ll ret = 0; sort(num, num + n + 1); int mv = 0; while (mv <= n) { int p = 0; while (p + mv <= n && num[p+mv] == num[mv]) p++; ret += p * (p-1) / 2; mv += p; } return ret;}int a[maxn], b[maxn];ll handle (int x, int pos) { int A = pos, B = n + 1 - pos; for (int i = 0; i < pos; i++) a[i] = s[i]; for (int i = pos; i <= n; i++) b[i-pos] = s[i]^(1<<x); sort(a, a + A); sort(b, b + B); ll ret = 0; int mva = 0, mvb = 0; while (mva < A && mvb < B) { if (a[mva] > b[mvb]) mvb++; else if (a[mva] < b[mvb]) mva++; else { int i = 0, j = 0; while (i + mva < A && a[i+mva] == a[mva]) i++; while (j + mvb < B && b[j+mvb] == b[mvb]) j++; ret += i * j; mva += i; mvb += j; } } return ret;}int main () { int cas; scanf("%d", &cas); while (cas--) { scanf("%s", str+1); n = strlen(str+1); int pos = -1; for (int i = 1; i <= n; i++) { if (str[i] == '?') { pos = i; break; } } ll ans = solve(); if (pos != -1) { for (int i = 0; i + 'a' <= 'z'; i++) ans += handle(i, pos); } printf("%d\n", ans); } return 0;}
HDU 1002
不知道,你寫的我有點看不懂,你可以考慮看看My Code吧。AC了的
代碼:
#include<stdio.h>
#include<string.h>
int main()
{
char a[5001],b[5001];
int aa[5001],bb[5001],k,n=0;
scanf("%d",&k);
for (int c=1;c<=k;c++)
{
scanf("%s%s",a,b);
int alen=strlen(a);
int blen=strlen(b);
memset(aa,0,sizeof(aa)); //清楚aa裡的數值,讓其為0
memset(bb,0,sizeof(bb));
int maxlen=blen;
if(alen>blen) maxlen=alen;
for(int i=alen-1;i>=0;i--)
aa[alen-i]=a[i]-'0';
for(int i=blen-1;i>=0;i--)
bb[blen-i]=b[i]-'0';
for(int i=1;i<=maxlen;i++)
{
aa[i]+=bb[i];
if(aa[i]>9)
{
if(i==maxlen) maxlen++;
aa[i+1]++;
aa[i]-=10;
}
}
printf("Case %d:\n",++n);
printf("%s + %s = ",a,b);
for(int i=maxlen;i>=1;i--)
printf("%d",aa[i]);
if (k==c)
printf("\n");
else
printf("\n\n");
}
return 0;
}
助我錯哪了? 杭電ACM1004http://acmhdueducn/showproblemphp?pid=1004
邏輯出錯了。
inital_num();
要放到while(ballnum != 0)的前面,不能放在迴圈裡。