昨天做了两道题,感觉挺水的,就没写题解。但是今天感觉还是纪念一下我的努力吧。
第一道是POJ 3630 Phone List
一道基础的Trie树,但是因为采用了动态建树,刚开始就TLE了。最后用了静态储存的方法就过了。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 100010; struct N { int next[11]; bool sign; }node[maxn]; string s; int sum; bool add() { int len = s.length(); int root = 0; for(int i = 0; i < len; i++) { int tmp = s[i] - ‘0‘; if(node[root].next[tmp]) { root = node[root].next[tmp]; if(i == len - 1) return 1; if(node[root].sign) return 1; } else { node[root].next[tmp] = sum; root = sum++; } if(i == len - 1) node[root].sign = 1; } return 0; } int main() { int t; cin >> t; while(t--) { sum = 1; bool flag = 1; memset(node, 0, sizeof(node)); int n; cin >> n; for(int i = 0; i < n; i++) { cin >> s; if(flag) if(add()) flag = 0; } if(flag) cout << "YES" << endl; else cout << "NO" << endl; } }
第二道是POJ 3067 Japan
是一道树状数组的题。也很简单,但是我也是因为犯了很低级的错误导致WA和TLE了几发。
最后调试的时候发现 树状数组的更新,如果传进去的参数为负数就会死循环,一下恍然大悟,负数加起来最后会是0,之后就死了。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
const int maxn = 1010;
struct N
{
int f, l;
} node[maxn * maxn];
int sum[maxn];
int n, m, k;
vector<int> p;
bool cmp(N a, N b)
{
return a.f > b.f;
}
void insert(int t)
{
while(t <= m)
{
sum[t] += 1;
t += t & (-t);
}
}
int findsum(int t)
{
t--;
int ret = 0;
while(t > 0)
{
ret += sum[t];
t -= t & (-t);
}
return ret;
}
void print()
{
for(int i = 1; i <= m; i++)
cout << i << " " << sum[i] << endl;
}
int main()
{
int t;
cin >> t;
for(int T = 0; T < t; T++)
{
memset(sum, 0, sizeof(sum));
cin >> n >> m >> k;
for(int i = 0; i < k; i++)
scanf("%d%d", &node[i].f, &node[i].l);
sort(node, node + k, cmp);
int tt = 0;
while(node[tt].f == node[0].f)
{
insert(node[tt].l);
tt++;
}
long long ans = 0;
for(int i = tt; i < k; i++)
{
if(node[i].f == node[i - 1].f)
{
ans += findsum(node[i].l);
p.push_back(node[i].l);
}
else
{
for(int j =