2013 Asia Regional Changchun

来源:互联网 发布:检测到您的网络异常 编辑:程序博客网 时间:2024/05/16 07:18

Find_Girl_Firend的第二次训练


http://acm.hdu.edu.cn/search.php?field=problem&key=2013+Asia+Regional+Changchun+&source=1&searchmode=source

hdu_4813 hdu_4815 hdu_4819 hdu_4821


A Hard Code


题意

不是我敲的。题目意思好像是把一个字符串分成N份长度为M的子串吧?GT手速慢,被他妹子强了FB。233333

code

#include<cstdio>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>#include<string>using namespace std;int t;string s;int main(){    cin>>t;    while(t--)    {        int n,m;        cin>>n>>m;        cin>>s;        int cnt=0;        for(int i=0;i<n;i++)        {            for(int j=0;j<m;j++)            {                cout<<s[cnt++];            }            cout<<endl;        }    }    return 0;}

C Little Tiger vs. Deep Monkey


题意

N道题目,每道题目分值为ai,答对得分,答错不得分。Monkey每次都是随机猜答案,所以每题答对的概率为0.5。问Tiger至少要得多少分才能使自己不输掉比赛的概率至少是p。

GT一直没给我翻对题目意思。后来自己默默的看了几遍。然后去拿外卖的时候把思路想通了。回来就A了。不过还是手残Wa了一发。

思路

思路比较简单,求出Monkey每种得分的概率。然后确定一个最小的m使得[0m]的得分的概率和sp
而每种概率的得分是个dp。
dp[i][j]表示前i题得分为j的概率。

dp[i][j]={dp[i1][j]×0.5dp[i1][ja[i]]×0.5+dp[i1][j]×0.5if(j<a[i])if(ja[i])
的矩阵。每次q个查询,x,y,c。以(x,y)为中心,c为边长的矩形可以包括的矩阵中的元素的最大值和最小值。然后把(x, y)点的值更新为(maxval+minval2)

思路

膜拜学弟啊。线段树套线段树。或者叫二维线段树吧?裸的。

code

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int MAXN = 800;const int INF = 999999999;int n, q;int sg_max[MAXN<<2][MAXN<<2];int sg_min[MAXN<<2][MAXN<<2];// int _cnt = 0;void create_y(int lx, int rx, int lrx, int ly, int ry, int lry) {    if (ly == ry) {        if (lx == rx) {            int tmp;            scanf ("%d", &tmp);            // _cnt ++;            sg_max[lrx][lry] = sg_min[lrx][lry] = tmp;        } else {            sg_max[lrx][lry] = max(sg_max[lrx << 1][lry], sg_max[lrx << 1 | 1][lry]);            sg_min[lrx][lry] = min(sg_min[lrx << 1][lry], sg_min[lrx << 1 | 1][lry]);        }        return ;    }    int m = (ly + ry) / 2;    create_y(lx, rx, lrx, ly, m, lry<<1);    create_y(lx, rx, lrx, m+1, ry, lry<<1|1);    sg_max[lrx][lry] = max(sg_max[lrx][lry << 1], sg_max[lrx][lry << 1 | 1]);    sg_min[lrx][lry] = min(sg_min[lrx][lry << 1], sg_min[lrx][lry << 1 | 1]);}void create_x(int lx, int rx, int lrx) {    if (lx == rx) {        create_y(lx, rx, lrx, 1, n, 1);        return ;    }    int m = (lx + rx) / 2;    create_x(lx, m, lrx<<1);    create_x(m+1, rx, lrx<<1|1);    create_y(lx, rx, lrx, 1, n, 1);}void update_y(int lx, int rx, int lrx, int ly, int ry, int lry, int _x, int _y, int _s) {    if (ly == ry ) {        if (lx == rx) {            sg_max[lrx][lry] = sg_min[lrx][lry] = _s;        } else {            sg_max[lrx][lry] = max(sg_max[lrx << 1][lry], sg_max[lrx << 1 | 1][lry]);            sg_min[lrx][lry] = min(sg_min[lrx << 1][lry], sg_min[lrx << 1 | 1][lry]);        }        return ;    }    int m = (ly + ry) / 2;    if (_y <= m) update_y(lx, rx, lrx, ly, m, lry << 1, _x, _y, _s);    if (_y >  m) update_y(lx, rx, lrx, m+1, ry, lry << 1 | 1, _x, _y, _s);    sg_max[lrx][lry] = max(sg_max[lrx][lry << 1], sg_max[lrx][lry << 1 | 1]);    sg_min[lrx][lry] = min(sg_min[lrx][lry << 1], sg_min[lrx][lry << 1 | 1]);}void update_x(int lx, int rx, int lrx, int _x, int _y, int _s) {    if (lx == rx && rx == _x) {        update_y(lx, rx, lrx, 1, n, 1, _x, _y, _s);        return ;    }    int m = (lx + rx) / 2;    if (_x <= m) update_x(lx, m, lrx << 1, _x, _y, _s);      if (_x >  m) update_x(m+1, rx, lrx << 1 | 1, _x, _y, _s);    update_y(lx, rx, lrx, 1, n, 1, _x, _y, _s); }int max_val, min_val;void query_y(int lx, int rx, int lrx, int ly, int ry, int lry, int Lx, int Rx, int Ly, int Ry) {    if (Ly <= ly && ry <= Ry) {        max_val = max(max_val, sg_max[lrx][lry]);        min_val = min(min_val, sg_min[lrx][lry]);        return ;    }     int m = (ly + ry) / 2;    if (Ly <= m) query_y(lx, rx, lrx, ly, m, lry << 1, Lx, Rx, Ly, Ry);    if (Ry >  m) query_y(lx, rx, lrx, m+1, ry, lry << 1 | 1, Lx, Rx, Ly, Ry);}void query_x (int lx, int rx, int lrx, int Lx, int Rx, int Ly, int Ry) {    if (Lx <= lx && rx <= Rx) {        query_y(lx, rx, lrx, 1, n, 1, Lx, Rx, Ly, Ry);        return ;    }    int m = (lx + rx) / 2;    if (Lx <= m) query_x(lx, m, lrx << 1, Lx, Rx, Ly, Ry);    if (Rx >  m) query_x(m+1, rx, lrx << 1 | 1, Lx, Rx, Ly, Ry);}int main () {    int T;    scanf ("%d", &T);    for (int cases = 1; cases <= T; cases++) {        scanf ("%d", &n);        create_x(1, n, 1);        // cout << "_cnt: " << _cnt << endl;        scanf ("%d", &q);        int tmp_x, tmp_y, tmp_l;        int Lx, Rx, Ly, Ry, S;        printf("Case #%d:\n", cases);        for (int i=0; i<q; i++) {            scanf ("%d%d%d", &tmp_x, &tmp_y, &tmp_l);            Lx = (tmp_x - tmp_l / 2) >  0 ? tmp_x - tmp_l / 2 : 1;            Rx = (tmp_x + tmp_l / 2) <= n ? tmp_x + tmp_l / 2 : n;            Ly = (tmp_y - tmp_l / 2) >  0 ? tmp_y - tmp_l / 2 : 1;            Ry = (tmp_y + tmp_l / 2) <= n ? tmp_y + tmp_l / 2 : n;            // cout << " -> " << Lx << " " << Rx << " " << Ly << " " << Ry << endl;            max_val = -INF;            min_val = INF;            query_x(1, n, 1, Lx, Rx, Ly, Ry);            // cout << "maxval :" << max_val << endl;            // cout << "minval :" << min_val << endl;            S = (max_val + min_val) / 2;            update_x(1, n, 1, tmp_x, tmp_y, S);            printf ("%d\n", S);        }    }    return 0;}

I String


题意

统计给定字符串S有多少个是”recoverable”串的子串。”recoverable”串定义为长度等于M×L,并且可分成连续的M个长度为L的子串。这M个子串不重复。

思路

确实想了好久,然而大神当年打这套现场赛的时候早就AC了。首先得得到这个字符串的所有的长度为L的子串的hash值。map就再见了。GT不造哪里学来的黑科技得出了这些子串的hash值。

然后枚举串的起点l(0l<L),对该起点可以找到M个连续的长度为L的子串。这里可以用map对这M个子串的hash值来判断是否出现重复。无重复则cnt++。然后可以删除头上的长度为L的子串,并在后面添加长尾L的子串。同样用map判重。同样无重复则cnt++

数据水了,GT强走了我的FB。也怪我手残写出一句,没有1A。

code

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <map>typedef unsigned long long  ull;using namespace std;const int maxn=100010;const ull seed=31;char str[100010];ull h[maxn];ull _hash[maxn];ull base[maxn];void init() {    base[0]=1;    for(int i=1;i<maxn;i++) {        base[i]=base[i-1]*seed;    }}int m, l;map<ull, int> mp;int main () {    init();    for (; scanf ("%d%d", &m, &l) == 2; ) {        scanf ("%s", str);        int len = strlen(str);        h[len]=0;        for(int i=len-1;i>=0;i--) {            h[i]=h[i+1]*seed+str[i]-'a'+1;        }        for (int i=0; i<len; i++) {            _hash[i]=h[i]-h[i+l]*base[l];            // cout << _hash[i] << " ";        }// cout << endl;        int ans = 0;        int L = l;        for (int i=0; i<L; i++) {            mp.clear();            int _cnt = 0;            int _l = i;            int _r = i;            for (int j=0; j<m; j++) {                if (mp[_hash[_r]] == 1) _cnt++;                mp[_hash[_r]] ++;                _r += L;            }//            cout << "i " << i << " _l: " << _l << " _r " <<  _r << endl;            if (_cnt == 0) ans++;            while (_r < len && _r + L -1 < len) {                if (mp[_hash[_r]] == 1) _cnt++;                mp[_hash[_r]]++;                if (mp[_hash[_l]] == 2) _cnt--;                mp[_hash[_l]]--;                _r += L;                _l += L;                if (_cnt == 0) ans++;            }        }        cout << ans << endl;    }    return 0;}
0 0