UESTC第二届ACM趣味程序设计竞赛第四场
A. Detectors
水题,判断有多少个点被若干个圆的并所覆盖,枚举下就行。
简单的记事本模拟,用链表来实现,有四个操作,插入字符,删除,左移,右移。注意链表记录的时候,要记录方向边,也就是双向的链表。
删除这个操作的时候,忘了更新。
代码
#include <iostream>
#include <string>
#include <stdio.h>
#include <string.h>
#include <set>
#include <algorithm>
#include <vector>
using namespace std;
const int MAX = 1000005;
int ind[MAX], top, p;
int val[MAX], rev[MAX];
void insert(int v)
{
ind[top] = ind[p];
if(ind[p] != -1) rev[ind[p]] = top;
ind[p] = top; rev[top] = p;
val[top++] = v;
if(ind[p] != -1) p = ind[p];
}
void del()
{
if(ind[p] != -1)
{
ind[p] = ind[ind[p]];
rev[ind[p]] = p;
}
}
int main()
{
int T, c = 0;
scanf("%d", &T);
while(T--)
{
int n;
top = 1; //ind[0]表示根节点
p = 0;
memset(ind, -1, sizeof(ind));
memset(rev, -1, sizeof(rev));
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
char com[10];
scanf("%s", com);
if(com[0] == 'I')
{
//getchar();
scanf("%s", com);
//insert(getchar());
insert(com[0]);
}
else if(com[0] == 'D')
{
del();
}
else if(com[0] == 'L')
{
if(rev[p] != -1) p = rev[p];
}
else if(com[0] == 'R')
{
if(ind[p] != -1) p = ind[p];
}
}
printf("Case #%d: ", ++c);
int x = ind[0];
while(x != -1)
{
printf("%c", val[x]);
x = ind[x];
}
printf("\n");
}
}
水题,把两个串按L长度剖分后,交替合并。
给定一个数列,和一个阈值K,求数列中连续子序列满足和小于K的个数。
枚举前n项和,然后二分查找子序列的左端,统计个数就行了。注意二分查找的时候,前n项和中可能有相等的值。
代码
#include <iostream>
#include <string>
#include <stdio.h>
#include <string.h>
#include <set>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long int64;
const int MAX = 1000005;
int64 a[MAX], b[MAX];
int N, A, B, C, M, K;
int64 go()
{
int64 res = 0;
b[1] = A, b[2] = B;
for(int i = 3; i <= N; i++)
{
b[i] = (int64(b[i - 1]) * b[i - 2] + C) % M;
}
a[1] = b[1];
for(int i = 2; i <= N; i++)
{
a[i] = a[i - 1] + b[i];
}
a[0] = 0;
//for(int i = 1; i <= N; i++) printf("@%d\n", a[i]);
for(int i = 1; i <= N; i++)
{
int low = 0, high = i;
while(low <= high)
{
int mid = (low + high) / 2;
if(a[i] - a[mid] < (int64)K) high = mid - 1;
else low = mid + 1;
}
res += (int64)i - low;
}
return res;
}
int main()
{
int T, c = 0;
scanf("%d", &T);
while(T--)
{
scanf("%d%d%d%d%d%d", &N, &A, &B, &C, &M, &K);
printf("Case #%d: %lld\n", ++c, go());
}
}
十进制与题目中的进(d1,d2,,,dn)制转换。
不理解进制的本质,若进制是(d1,d2,,,dn),从低位到高位,则该数按该进制展开后是
X = a0 + a1 * d1 + a2 * d1 * d2 + a3 * d1 * d2 * d3 + ... + an * d1 * d2 * ... * dn