2020年湖南省大学生计算机程序设计竞赛
A 2020
一个简单的 DP,f[i]
表示前i
位最多能选择的子串个数。
转移首先不选可以得到f[i] = f[i-1]
,其次如果当前的后缀是2020
的话就f[i] = max( f[i] , f[i-4]+1)
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
char s[N];
int f[N];
int32_t main() {
int n;
while( cin >> n ){
f[0] = 0;
scanf("%s" , s+1 );
for( int i = 4 ; i <= n ; i ++ ){
f[i] = f[i-1];
if( s[i-3] == '2' && s[i-2] == '0' && s[i-1] == '2' && s[i] == '0')
f[i] = max( f[i] , f[i-4] + 1 );
}
int res = 0;
for( int i = 1 ; i <= n ; i ++ )
res = max( res , f[n] ) ;
cout << res <<"\n";
}
return 0;
}
B 2020 vs 2018
这道题的做法很多样,我的做法是找1
,1
有一个特点是最上面一位的上左右的没有是很特殊的,以此来判断即可
#include<bits/stdc++.h>
using namespace std;
const int N = 55;
string s[N];
int32_t main() {
int n , m;
while( cin >> n >> m ){
for( int i = 0 ; i < n ; i ++ )
cin >> s[i];
int f = 0;
for( int i = 0 ; i < n && !f ; i ++ )
for( int j = 0 ; j < m && !f ; j ++ ){
if( s[i][j] != 'o' || s[i-1][j] == 'o' ) continue;
if( j > 0 && s[i][j-1] == 'o' ) continue;
if( j + 1 == m || s[i][j+1] != 'o' ) f = 1 ;
}
cout << ( f ? "2018\n" : "2020\n" );
}
return 0;
}
G 奇矩阵
首先可以把所有的书全部模二,然后两行的差值的奇偶情况就是两个行异或一下,异或后奇数的个数是奇数个那么和就是奇数。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+5;
bitset<N> st[N];
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int32_t main() {
int n , m;
while( cin >> n >> m ){
for( int i = 1 ; i <= n ; i ++ ) {
st[i].reset(1);
for( int j = 1 , x ; j <= m ; j ++ )
x = read() , st[i][j] = x & 1;
}
int f = 1;
for( int i = 1 ; i <= n && f ; i ++ )
for( int j = i + 1 ; j <= n && f ; j ++ ){
if( (st[i] ^ st[j]).count() % 2 == 0 ) f = 0 ;
}
cout << ( f ? "Yes\n" : "No\n" );
}
return 0;
}
I 共线点
首先把三条直线排序,让最上面的和最下面的连线看能否经过中间的。然后分别找一下两条线最左边的和最右边的两条线,然后如果端点在这两条边之外就是无法相交
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 5;
struct Node{
int a , b ,y;
Node( int a , int b , int y ) : a(a) , b(b) , y(y) {};
Node(){};
} s[N];
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int32_t main() {
while( cin >> s[1].a >> s[1].b >> s[1].y ){
for( int i = 2 ; i <= 3 ; i ++ )
cin >> s[i].a >> s[i].b >> s[i].y;
int h = s[3].y - s[1].y;
int da = s[3].a - s[1].a;
int dy = s[2].y - s[1].y;
int db = s[3].b - s[1].b;
if( s[1].a * h + da * dy > s[2].b * h ) cout << "No\n";
else if( s[1].b * h + db * dy < s[2].a * h ) cout << "No\n";
else cout << "Yes\n";
}
return 0;
}
H 矩形并
首先有一个结论从(0,0)
到(a,b)
所有矩形面积之和是\((1+2+3+\cdots+a)\times(1+2+3+\cdots+b)\)这样
设矩形 A的面积是\(S\),那么答案就是\(\frac{a\times(a+1)}{2}\times\frac{b\times(b+1)}{2}+a\times b\times S-V\),其中\(V\)是矩形相交的面积
相交的情况有三种,分别是i<=x2&&j<=y2
,i<=x2&&j >y2 || i>x2&&j<=y2
,i>x2&&j>y2
三种情况分类讨论,然后逐个减去,注意容斥就好
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 1e9+7 , inv=500000004;
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int32_t main() {
int a , b , x1 , x2 , y1 , y2 , res , s;
while( cin >> a >> b ){
cin >> x1 >> x2 >> y1 >> y2;
s = ( x2 - x1 ) % mod * ( y2 - y1 ) % mod;
res = ( a * (a+1) % mod * inv % mod ) % mod * ( b * (b+1) % mod * inv % mod ) % mod + (a * b % mod * s % mod ) % mod ;
if( a >= x1 && b >= y1 ){
a -= x1 , b -= y1 , x2 -= x1 , y2 -= y1;
int tx = min( a , x2 ) , ty = min( b , y2 );
res = (res - (tx * (tx+1) % mod * inv % mod * ty % mod * (ty+1) % mod * inv) % mod + mod ) % mod ;
int tb = b - y2 , ta = a - x2;
if( tb > 0 ){
res = ( res - ( tb * tx % mod * (tx+1) % mod * inv % mod * y2 % mod ) + mod ) % mod;
}
if( ta > 0 ){
res = (res - ( ta * ty % mod * (ty+1) % mod * inv % mod * x2 % mod ) + mod ) % mod;
}
if( ta > 0 && tb > 0 ){
res = ( res - ( ta * tb % mod * s % mod ) + mod ) % mod;
}
}
cout << res % mod << "\n";
}
}