hdu4963 中途相遇

2021-07-02 19:00:44 字數 1415 閱讀 1987

將序列分成兩半,各n各字元。對於前一半,列舉每個字元屬於t1還是t2,共2^n種情況。在乙個方案中,t1的子串行為a,t2的子串行為b,我們假定a的長度不大於b的長度。顯然,a是b的字首才符合要求。令c=b-a,即b去掉a字首後剩餘的部分。同理,處理後一半得到乙個c『,就是去掉相同字尾後剩餘的部分。當c=c'就是乙個方案使得t1=t2。

主要有兩點十分巧妙:1.列舉過程可以控制t1長度<=t2,這樣能減少一半的列舉,但是會漏掉一些情況,比如第乙個字元總是放在t2,實際也能放在t1,於是在len1==len2時另外交換兩個串進行列舉。

2.如何快速匹配呢?我們記錄的是兩部分的權值之差,應該是取兩部分w1-w2之和絕對值最小,可以變換為第一部分w1-w2和第二部分w2-w1之差絕對值最小,這樣我們就記錄第一部分的w1-w2,第二部分的w2-w1,現根據c排序,在根據權值之差排序,於是相鄰的c和c'之差最小,可以o(n)解決。另外由於記憶體不夠,把字串c轉化成數字,並記錄長度,按長度排序再按c大小排序再按權值排序。

#include#include#include#include#include#include#include#include#include#include#define inf 1000000000

#define pi acos(-1.0)

#define eps 1e-8

#define seed 131

using namespace std;

typedef pairpii;

typedef unsigned long long ull;

typedef long long ll;

const int maxn=100005;

char s[50];

int d[50];

int n;

struct node

vec[num].p=m;

vec[num++].w=w2-w1;

if(len1==len2)

return;

}t1[len1++]=s[u];

w1+=d[u];

dfs2(u+1);

len1--;

w1-=d[u];

if(len1==len2)

if(len2=0&&(vec[i].p!=vec[i-1].p||vec[i].len!=vec[i-1].len))

q=-1;

}if(vec[i].flag==0)

if(p==-1||q==-1)

continue;

ans=min(ans,abs(vec[p].w-vec[q].w));

}if(ans==inf)

printf("-1\n");

else

printf("%d\n",ans);

}return 0;

}

HDU 5936 中途相遇法

題目位址 這道題關鍵在於f y,k y可以拆成f a,k f b,k a1e5 b 我們就把y的1e9範圍降到了1e5 然後我們可以對前一半1e5個數枚舉出x f a,k a1e5 然後對於後一半1e5個數用二分找到有多少和f b,k b相同的就是個數。注意當x等於零的時候會有a 0,b 0的情況,...

LA 2965 中途相遇法

題意 有很多字串 24 選出一些字串,要求這些字串的字母都是偶數次 分析 暴力2 24也很大了,中途相遇法 其原理就是一分為二,兩組解組成問題的解 考慮到,每個字串出現的次數沒什麼關係,只要關於他的奇偶,那麼就有二進位制,1出現奇數次,0偶數次 每乙個字串對應於乙個a位向量,在前半個表中,選擇一些字...

UVA 10125 中途相遇法

題意 給定乙個整數集合,找出最大的d,使得a b c d,a,b,c,d是集合中不同的元素 思路 如果單純的列舉a,b,c的複雜度是o n 3 的,為了降低複雜度,可以先把a b的情形都找出來,然後再列舉d和c,是否符合要求 ac include include include include in...