Table of Contents
codeforces----1016
codeforces----1016A
codeforces----1016B
codeforces----1016C
codeforces----1016D
codeforces----1016E
http://codeforces.com/problemset/problem/1016/A
水
#include
using namespace std;
int main() {
int n, m;
while ( cin >> n >> m ) {
int now = 0, temp;
while ( n-- ) {
cin >> temp;
now += temp;
cout << now / m << ' ';
now = now % m;
}
cout<
问子串在母串中出现的次数
kmp查询
#include
#include
#include
#include
using namespace std;
int next[1008];
vectorans;
void setnext ( char *a ) {
int i = 0, j = -1;
next[0] = -1;
while ( a[i] ) {
if ( j == -1 || a[i] == a[j] ) next[++i] = ++j;
else j = next[j];
}
}
void kmp ( char *a, char *b ) {
int i = 0, j = 0, m = strlen ( b );
while ( a[i] ) {
if ( j == -1 || a[i] == b[j] )++i, ++j;
else j = next[j];
if ( j == m ) {
ans.push_back ( i );
j = next[j];
}
}
}
int main() {
int n, m, k;
while ( cin >> n >> m >> k ) {
char s1[1008], s2[1008];
cin >> s1 >> s2;
ans.clear();
setnext ( s2 );
kmp ( s1, s2 );
while ( k-- ) {
int temp1, temp2, a = 0;
cin >> temp1 >> temp2;
for ( vector::iterator it = ans.begin(); it != ans.end(); it++ )
if ( temp1 <= *it && temp1 <= *it - m + 1 && *it <= temp2 && *it + 1 - m <= temp2 )
a++;
cout << a << endl;
}
}
return 0;
}
http://codeforces.com/problemset/problem/1016/C
从左上角出发的一条路径(a1~~an),求最大的1*a1+2*a2+...+n*an
dp的记忆化数组(我这个写的不好。)
#include
#include
#include
#include
using namespace std;
#define f(a) ((a)==0?1:0)
long long in[2][300008], n;
long long a[2][300008], ra[2][300008];
long long b[2][300008], rb[2][300008];
long long func1 ( int x, int y, int val ) {
if ( y == n ) return val * in[x][y] + ( val + 1 ) * in[f ( x )][y];
long long fin = b[x][n] - b[x][y - 1] + ( a[x][n] - a[x][y - 1] ) * ( val - y ) ;
fin += rb[f ( x )][y] + ra[f ( x )][y] * ( val + n - y );
return max ( fin, in[f ( x )][y] * ( val + 1 ) + in[x][y] *val + func1 ( f ( x ), y + 1, val + 2 ) );
}
int main() {
while ( cin >> n ) {
for ( int i = 0; i < 2; i++ )
for ( int j = 1; j <= n; j++ )
scanf ( "%d", &in[i][j] );
a[0][0] = a[1][0] = 0;
for ( int k = 0; k < 2; k++ )
for ( int i = 1; i <= n; i++ )
a[k][i] = in[k][i] + a[k][i - 1];
ra[0][n + 1] = ra[1][n + 1] = 0;
for ( int k = 0; k < 2; k++ )
for ( int i = n; i >= 1; i-- )
ra[k][i] = in[k][i] + ra[k][i + 1];
b[0][0] = b[1][0] = 0;
for ( int k = 0; k < 2; k++ )
for ( int i = 1; i <= n; i++ )
b[k][i] = i * in[k][i] + b[k][i - 1];
rb[0][n + 1] = rb[1][n + 1] = 0;
for ( int k = 0; k < 2; k++ )
for ( int i = n; i >= 1; i-- )
rb[k][i] = ( n - i + 1 ) * in[k][i] + rb[k][i + 1];
printf ( "%I64d\n", func1 ( 0, 1, 0 ) );
}
return 0;
}
http://codeforces.com/problemset/problem/1016/D
给你一个矩阵的每行每列的异或值,如果存在就构造一个。
首先对所有的值异或一次,因为矩阵的每个点都会被访问两次,因此异或值必须为0
构造矩阵时我们靠任何值异或0都是其本身的特点,只构造最后一行一列,显然除了右下角的都直接构造。
类似于这样
0 0 0 0 0 0 0 0 0 a1 0 0 0 0 0 0 0 0 0 a2 0 0 0 0 0 0 0 0 0 a3 0 0 0 0 0 0 0 0 0 a4 0 0 0 0 0 0 0 0 0 a5 0 0 0 0 0 0 0 0 0 a6 0 0 0 0 0 0 0 0 0 a7 0 0 0 0 0 0 0 0 0 a8 0 0 0 0 0 0 0 0 0 a9 b1 b2 b3 b4 b5 b6 b7 b8 b9 t
我们要知道 a1^a2^...^an-1^t=bn 因此 t=a1^a2^...an-1^bn。显然有关数组b的同理。因此只要选一个方案求 t 即可
#include
#include
#include
#include
using namespace std;
int main() {
int n, m;
while ( cin >> n >> m ) {
int in[2][108], temp = 0;
for ( int i = 0; i < n; i++ )
cin >> in[0][i], temp = temp ^ in[0][i];
for ( int i = 0; i < m; i++ )
cin >> in[1][i], temp = temp ^ in[1][i];
if ( temp != 0 ) {
cout << "NO" << endl;
continue;
} else cout << "YES" << endl;
for ( int i = 0; i < n; i++ )
for ( int j = 0; j < m; j++ )
if ( j == m - 1 && i == n - 1 ) {
temp = in[0][n - 1];
for ( int k = 0; k < m - 1; k++ )
temp = temp ^ in[1][k];
cout << temp << endl;
} else if ( j == m - 1 ) cout << in[0][i] << endl;
else if ( i == n - 1 ) cout << in[1][j] << ' ';
else cout << "0 ";
}
return 0;
}
http://codeforces.com/problemset/problem/1016/E
一个光源的移动区间,多个挡板,多次查询,问查询点在阴影范围的时间。
数据很大,思路是进行线段树优化。
因此,藉由光源和查询点,由相似性 覆盖到挡板区间,通过判断挡板遮盖的比例来判断时间
线段树进行时间优化。
ps.我不知道输入选择浮点型,我的代码非浮点型 Wrong answer on test 3 ,我看输入写的都是整形常量啊。。
#include
#include
#include
#include
using namespace std;
double Left, Right;
class AP {
public:
double l, r, val;
} tree[800008];
void pushup ( int i ) {
tree[i].l = tree[2 * i].l;
tree[i].r = tree[2 * i + 1].r;
tree[i].val = tree[2 * i].val + tree[2 * i + 1].val;
}
void build ( int i, int L, int R ) {
if ( L == R ) {
scanf ( "%lf%lf", &tree[i].l, &tree[i].r );
tree[i].val = tree[i].r - tree[i].l;
return;
}
int mid = ( L + R ) / 2;
build ( 2 * i, L, mid );
build ( 2 * i + 1, mid + 1, R );
pushup ( i );
}
double sum ( int i, int L, int R ) {
if ( Left <= tree[i].l && tree[i].r <= Right ) return tree[i].val;
if ( L == R )
if ( Right < tree[i].l || tree[i].r < Left ) return 0;
else return min ( Right, tree[i].r ) - max ( Left, tree[i].l );
int mid = ( L + R ) / 2;
double ans = 0;
if ( Left <= tree[2 * i].r && Right >= tree[2 * i].l ) ans += sum ( 2 * i, L, mid );
if ( Left <= tree[2 * i + 1].r && Right >= tree[2 * i + 1].l ) ans += sum ( 2 * i + 1, mid + 1, R );
return ans;
}
double point[200003][2];
int main() {
int sy, a, b;
while ( ~scanf ( "%d%d%d", &sy, &a, &b ) ) {
int n, m;
sy = -sy;
scanf ( "%d", &n );
build ( 1, 1, n );
scanf ( "%d", &m );
for ( int i = 0; i < m; i++ )
scanf ( "%lf%lf", &point[i][0], &point[i][1] );
for ( int i = 0; i < m; i++ ) {
Left = 1.0 * ( sy * point[i][0] + point[i][1] * a ) / ( sy + point[i][1] );
Right = 1.0 * ( sy * point[i][0] + point[i][1] * b ) / ( sy + point[i][1] );
printf ( "%.6lf\n", sum ( 1, 1, n ) / ( Right - Left ) * ( b - a ) );
}
}
return 0;
}