Find_Girl_Firend的第二次训练
hdu_4813 hdu_4815 hdu_4819 hdu_4821
A Hard Code
题意
不是我敲的。题目意思好像是把一个字符串分成
N
份长度为
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
道题目,每道题目分值为
GT一直没给我翻对题目意思。后来自己默默的看了几遍。然后去拿外卖的时候把思路想通了。回来就A了。不过还是手残Wa了一发。
思路
思路比较简单,求出Monkey每种得分的概率。然后确定一个最小的
m
使得
而每种概率的得分是个dp。
dp[i][j]表示前i题得分为j的概率。
code
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int T, n;
double p;
int a[42];
double dp[42][40 * 1000 + 2];
int sum = 0;
int main () {
scanf ("%d", &T);
for (int _case = 1; _case <= T; _case++) {
scanf ("%d%lf", &n, &p);
sum = 0;
for (int i=1; i<=n; i++) {
scanf ("%d", &a[i]);
sum += a[i];
}
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for (int i=1; i<=n; i++) {
for (int j=0; j<=sum; j++) {
if (j >= a[i]) dp[i][j] = dp[i-1][j] * 0.5 + dp[i-1][j-a[i]] * 0.5;
else dp[i][j] = dp[i-1][j] * 0.5;
}
}
double _s = 0.0;
int ans = -1;
for (int i=0; i<=sum; i++) {
_s += dp[n][i];
if (_s >= p) {
ans = i;
break;
}
}
printf ("%d\n", ans);
}
return 0;
}
G Mosaic
题意
一个
n×n
的矩阵。每次
q
个查询,
思路
膜拜学弟啊。线段树套线段树。或者叫二维线段树吧?裸的。
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”串定义为长度等于
思路
确实想了好久,然而大神当年打这套现场赛的时候早就AC了。首先得得到这个字符串的所有的长度为L的子串的 hash 值。map就再见了。GT不造哪里学来的黑科技得出了这些子串的 hash 值。
然后枚举串的起点
l(0≤l<L)
,对该起点可以找到
M
个连续的长度为
数据水了,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;
}