“强智杯“2020年湖南省大学生计算机程序设计竞赛——ABDGHI
oj: 链接A.2020oj: 链接题解直接暴力维护即可。代码#include <bits/stdc++.h>#define PI atan(1.0)*4#define rp(i,s,t) for ( int i = (s); i <= (t); i++)#define RP(i,t,s) for ( int i = (t); i >= (s); i--)#define s
oj: 链接
A.2020
oj: 链接
题解
直接暴力维护即可。
代码
#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for ( int i = (s); i <= (t); i++)
#define RP(i,t,s) for ( int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
void solve(){
int n;
while(cin>>n){
string s;cin>>s;
int ans=0;
rp(i,0,n-1){
if(i+3<=n-1&&s[i]=='2'&&s[i+1]=='0'&&s[i+2]=='2'&&s[i+3]=='0'){
i=i+3;
ans++;
}
// outval2(i,ans);
}
cout<<ans<<endl;
}
}
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
//debug = 1;
#endif
//time_t beg, end;
//if(debug) beg = clock();
solve();
/*
if(debug) {
end = clock();
printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
}
*/
return 0;
}
B.2020 vs 2018
oj: 链接
题解
观察在
2018
2018
2018和
2020
2020
2020的图像可以发现,
最明显的区别在于
2018
2018
2018多了一个
1
1
1。
因此我们直接暴力枚举是否有
1
1
1即可。
代码
#include <bits/stdc++.h>
using namespace std;
#define _for(i, a) for(int i = 0, len = a; i < len; ++i)
#define _rep(i, a, b) for(int i = a, len = b; i <= len; ++i)
#define outval(a) cout << "debuging|" << #a << ":" << a << "\n";
#define dg if(debug)
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int maxn = 1005;
int debug = 0;
inline LL read() {
LL x(0), f(1); char ch(getchar());
while(ch < '0' || ch > '9') {
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
struct poi {
};
int n, m;
char s[57][57];
void init() {
_rep(i,1,n) scanf("%s",s[i]+1);
_rep(i,1,n){
dg outval(i);
_rep(j,i,n){
dg outval(j);
_rep(k,1,m){
int f=1;
if(i>1&&s[i-1][k]=='o') continue;
if(j<n&&s[j+1][k]=='o') continue;
_rep(l,i,j){
if(s[l][k]!='o'){
f=0;
break;
}
if(k>1){
if(s[l][k-1]=='o'){
f=0;
break;
}
}
if(k<m){
if(s[l][k+1]=='o'){
f=0;
break;
}
}
}
if(f){
puts("2018");
return ;
}
}
}
}
_rep(i,1,m){
_rep(j,i,m){
_rep(k,1,n){
int f=1;
if(i>1&&s[k][i-1]=='o') continue;
if(j<m&&s[k][j+1]=='o') continue;
_rep(l,i,j){
if(s[k][l]!='o'){
f=0;
break;
}
if(k>1){
if(s[k-1][l]=='o'){
f=0;
break;
}
}
if(k<n){
if(s[k+1][l]=='o'){
f=0;
break;
}
}
}
if(f){
puts("2018");
return ;
}
}
}
}
puts("2020");
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
// debug = 1;
#endif
while(~scanf("%d%d",&n,&m)) init();
return 0;
}
D.String Commutativity
oj: 链接
题解
如果两个串有相同的最短循环节,则这两个串符合题目要求。用kmp求最短循环节,但kmp求出的最短循环节不一定符合题意,例如aba的最短循环节为ab,而kmp求出的为aba,所以应排除这种情况。即用m%x!=0判断是否最后一个循环节是否完全循环
代码
#include <cstring>
#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <map>
using namespace std;
const int maxn=1e6+7;
const int INF=0x3f3f3f3f;
#define M 50015
int next1[maxn];
char str[maxn],mo[maxn];
int ans;
map<string,int> mp;
string tran(int x){
string a;
for(int i=0;i<x;i++){
a.push_back(mo[i]);
}
return a;
}
void getnext()
{
int i=0,j=-1,m=strlen(mo);
while(i<m){
if(j==-1||mo[i]==mo[j])
next1[++i]=++j;
else
j=next1[j];
}
}
int main()
{
int t;
while(~scanf("%d",&t)){
mp.clear();
long long sum=0;
while(t--){
ans=0;
scanf("%s",mo);
next1[0]=-1;
getnext();
int m=strlen(mo);
int x=m-next1[m];
if(x<m&&m%x!=0){
x=m;
}
//printf("x:%d\n", x);
string y=tran(x);
mp[y]++;
}
map<string,int>::iterator it;
it=mp.begin();
while(it!=mp.end()){
int n=it->second;
sum+=1LL*n*(n-1)/2;
it++;
}
printf("%lld\n",sum);
}
return 0;
}
G.奇矩阵
oj: 链接
题解
可以直接暴力枚举过,时间复杂度:
O
(
n
2
)
O(n^{2})
O(n2)。
O
(
n
)
O(n)
O(n)的做法:
先说结论
记录每一行数的和的奇偶性,
如果奇数的次数是否大于
1
1
1且偶数的次数大于
1
1
1肯定不是奇矩阵,否则是。
证明如下:
假设当前有
m
m
m列数,取两行数分别为:
x
1
,
x
2
,
.
.
.
,
x
m
x_{1},x_{2},...,x_{m}
x1,x2,...,xm。
y
1
,
y
2
,
.
.
.
,
y
m
y_{1},y_{2},...,y_{m}
y1,y2,...,ym。
令
d
1
=
x
1
−
y
1
d_{1}=x_{1}-y_{1}
d1=x1−y1,
d
2
=
x
2
−
y
2
d_{2}=x_{2}-y_{2}
d2=x2−y2,
d
3
=
x
3
−
y
3
d_{3}=x_{3}-y_{3}
d3=x3−y3,
…
d
m
=
x
m
−
y
m
d_{m}=x_{m}-y_{m}
dm=xm−ym
假设两行数的和都为偶数,那么可以得到
(
d
1
+
d
2
+
.
.
.
+
d
m
)
(d_{1}+d_{2}+...+d_{m})
(d1+d2+...+dm)%
2
=
0
2=0
2=0。
因为题目给的是绝对值求和,
如果当前差值是
d
i
d_{i}
di,
如果
d
i
d_{i}
di为正数没有影响,
如果
d
i
d_{i}
di为负数的话对答案的影响是加上
2
×
∣
d
i
∣
2\times |d_{i}|
2×∣di∣。
那么可以发现
(
d
1
+
d
2
+
.
.
.
+
d
m
+
2
×
∣
d
i
∣
)
(d_{1}+d_{2}+...+d_{m}+2\times |d_{i}|)
(d1+d2+...+dm+2×∣di∣)%
2
=
0
2=0
2=0,即对答案的奇偶性没有影响。
因此结论得证。
代码
#include <bits/stdc++.h>
using namespace std;
#define _for(i, a) for(int i = 0, len = a; i < len; ++i)
#define _rep(i, a, b) for(int i = a, len = b; i <= len; ++i)
#define outval(a) cout << "debuging|" << #a << ":" << a << "\n";
#define dg if(debug)
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int maxn = 1005;
int debug = 0;
inline LL read() {
LL x(0), f(1); char ch(getchar());
while(ch < '0' || ch > '9') {
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
struct poi {
};
int n, m;
int num[2];
void init() {
num[0] = num[1] = 0;
}
int sol() {
init();
_for(i, n) {
LL sum = 0;
_for(j, m) sum += read();
++num[sum & 1];
}
if(num[0] > 1 || num[1] > 1) return 0;
return 1;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
debug = 1;
#endif
while(cin>>n>>m) {
printf("%s\n", sol() ? "Yes":"No");
}
return 0;
}
H.矩阵并
oj: 链接
题解
分情况容斥一下即可求出答案。
参考下图
代码
#include <bits/stdc++.h>
using namespace std;
#define _for(i, a) for(int i = 0, len = a; i < len; ++i)
#define _rep(i, a, b) for(int i = a, len = b; i <= len; ++i)
#define outval(a) cout << "debuging|" << #a << ":" << a << "\n";
#define dg if(debug)
typedef long long LL;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
const int maxn = 1005;
const LL mod = 1000000007;
int debug = 0;
inline LL read() {
LL x(0), f(1); char ch(getchar());
while(ch < '0' || ch > '9') {
if(ch == '-') f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
struct poi {
};
LL a, b;
void exgcd(LL a, LL b, LL &g, LL &x, LL &y) {
if (!b) {
g = a;
x = 1;
y = 0;
} else {
exgcd(b, a % b, g, y, x);
y -= x * (a / b);
}
}
LL inv(LL x, LL mod) {
LL a, k, g;
exgcd(x, mod, g, a, k);
if(a < 0) a += mod;
return a;
}
LL getval(LL a, LL b) {
LL ans = 0;
ans += a * a % mod * b % mod * b;
ans += a * b % mod * b % mod;
ans += a * a % mod * b % mod;
ans += a * b % mod;
ans %= mod;
ans *= inv(4, mod);
return ans % mod;
}
int sol() {
LL x = read(), xx = read(), y = read(), yy = read();
LL ans = 0;
ans += getval(a, b);
dg printf("累积:%lld\n", getval(a, b));
LL w1 = max(0LL, min(b, yy) - y);
LL box1 = w1 * (w1 + 1) % mod * inv(2, mod) % mod * max(0LL, a - xx) % mod * (xx - x) % mod;
LL w2 = max(0LL, min(a, xx) - x);
if(a < x) w2 = 0;
dg printf("w1:%lld\tw2:%lld\n", w1, w2);
LL box2 = w2 * (w2 + 1) % mod * inv(2, mod) % mod * max(0LL, b - yy) % mod * (yy - y) % mod;
LL box3 = max(0LL, a - xx) * max(0LL, b - yy) % mod * (xx - x) % mod * (yy - y) % mod;
LL ans2 = box1 + box2 + box3 + getval(max(0LL, min(a, xx) - x), max(0LL, min(b, yy) - y)); ans2 %= mod;
dg printf("box1:%lld\tbox2:%lld\tbox3:%lld\n", box1, box2, box3);
dg printf("减去:%lld\n", ans2);
ans += mod - ans2;
LL ans3 = (xx - x) * (yy - y) % mod * a % mod * b % mod;
ans += ans3;
dg printf("额外:%lld\n", ans3);
ans %= mod;
printf("%lld\n", ans);
return 0;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
// debug = 1;
#endif
while(~scanf("%lld%lld", &a, &b)) {
sol();
}
return 0;
}
I.共线点
oj: 链接
题解
首先把三个线段按照高度排序,
然后用最高的线段的左端点和最低的线段的左端点连接成一条直线,
求出这个直线方程,把中间线段的
y
y
y值带入,这样求出的是有效区间的左端点。
同理可以得到有效区间的右端点。
判断一下中间线段是否和这个有效区间是否有交点即可。
求端点可以利用两点式快速求出来。
代码
#include <bits/stdc++.h>
using namespace std;
#define _for(i, a) for(int i = 0, len = a; i < len; ++i)
#define _rep(i, a, b) for(int i = a, len = b; i <= len; ++i)
#define outval(a) cout << "debuging|" << #a << ":" << a << "\n";
#define dg if(debug)
typedef long long LL;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
const int maxn = 1005;
int debug = 0;
inline LL read() {
LL x(0), f(1); char ch(getchar());
while(ch < '0' || ch > '9') {
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
struct poi {
int a, b, y;
bool operator<(const poi &b) const {
if(y != b.y) return y < b.y;
else if(a != b.a) return a < b.a;
else return this->b < b.b;
}
};
poi a[3];
void init() {
}
int sol() {
_rep(i, 1, 2) {
int aa, bb, yy;
scanf("%d%d%d", &aa, &bb, &yy);
a[i] = {aa, bb, yy};
}
sort(a, a + 3);
double x1 = 1.0 * (a[2].a - a[0].a) / (a[2].y - a[0].y) * (a[1].y - a[0].y) + a[0].a;
double x2 = 1.0 * (a[2].b - a[0].b) / (a[2].y - a[0].y) * (a[1].y - a[0].y) + a[0].b;
dg printf("xx1:%.2f\txx2:%.2f\n", x1, x2);
if(x1 - eps <= a[1].b && x2 + eps >= a[1].a) return 1;
return 0;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
debug = 1;
#endif
int aa, bb, yy;
while(~scanf("%d%d%d", &aa, &bb, &yy)) {
a[0] = {aa, bb, yy};
printf("%s\n", sol () ?"Yes":"No");
}
return 0;
}
更多推荐
所有评论(0)