Codeforces Round #578
C题:
- 在圆上分区间,内圆分成n等分,外院分成m等分,当内外圆同时有同一个区间端点的时候,那么就不能通行。
- 数论,gcd就行了,令g=gcd(n,m),那么可以看出,内圆与外圆交接的点,有n/g,2*n/g ... m/g,2 *m/g.....所以就只用判断是否在同一个点的区间内就好。
#include<iostream>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
char ch = getchar(); ll x = 0, f = 1;
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;
}
typedef pair<int, int> pir;
ll n, m;
ll sx, sy, ex, ey;
int q;
ll gcd(ll a, ll b)
{
return b? gcd(b, a % b) : a;
}
int main()
{
scanf("%lld %lld", &n, &m);
q = read();
ll g = gcd(n, m);
while (q--)
{
sx = read(), sy = read(), ex = read(), ey = read();
sy--, ey--;
ll temp1 = sx == 1 ? sy / (n / g) : sy / (m / g);
ll temp2 = ex == 1 ? ey / (n / g) : ey / (m / g);
cout << (temp1 == temp2 ? "YES":"NO") << endl;
}
return 0;
}
D题
- 给出n*n的矩阵,由黑白构成,现在有一个k*k的矩阵,可以做一次清除工作,
使得k*k矩阵内全部变为白色,消除矩阵不能越界,问,怎么做才能使得原来的矩阵,白色的行列之和最大。 - 我们使用尺取法来解决。我们以(i,j)为右上角的矩形,对于矩形内部,我们对于行列分开处理,k行内,如果有一行,最左端的黑色和最右端的黑色,都在消除矩阵内,那么ans++,同理列。那么对于(i+1,j)来说,他对答案的贡献,就是ans-(第i行的贡献)+(j+k行的贡献)。所以只需要一开始遍历一遍k的矩阵,然后就可以使用尺取来保证复杂度不会t掉。
#include<iostream>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
int read()
{
char ch = getchar(); int x = 0, f = 1;
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;
}
typedef pair<int, int> pir;
const int N = 2e3 + 10;
int n, k;
char grp[N][N];
int rows[N][2];
int cols[N][2];
int ans[N][N];
int main()
{
n = read(), k = read();
upd(i, 1, n)
{
scanf("%s", grp[i]+1);
}
upd(i, 1, n)
{
upd(j, 1, n)
{
if (grp[i][j] == 'W')continue;
if (rows[i][0] == 0)rows[i][0] = j;
rows[i][1] = max(rows[i][1], j);
}
}
upd(j, 1, n)
{
upd(i, 1, n)
{
if (grp[i][j] == 'W')continue;
if (cols[j][0] == 0)cols[j][0] = i;
cols[j][1] = max(cols[j][1], i);
}
}
int anscol = 0, ansrow = 0;
upd(i, 1, n)
{
if (cols[i][0] == 0)ansrow++;
if (rows[i][0] == 0)anscol++;
}
upd(i,1, n - k + 1)
{
int summ = 0;
upd(j, 1, k)
{
if (cols[j][0]!=0)
{
summ+=i<=cols[j][0]&&cols[j][1]<=i+k-1;
}
}
ans[i][1] = summ;
upd(j, 2, n - k+1)
{
if (cols[j - 1][0] != 0)
summ-= i <= cols[j-1][0] && cols[j-1][1] <= i+k-1;
if (cols[j+k-1][0]!=0)summ+= i <= cols[j+k-1][0] && cols[j+k-1][1] <= i + k-1;
ans[i][j] = summ;
}
}
upd(j, 1, n - k + 1)
{
int summ = 0;
upd(i, 1, k)
{
if (rows[i][0] != 0)
{
summ += j <= rows[i][0] && rows[i][1] <= j + k-1;
}
}
ans[1][j] += summ;
upd(i, 2, n - k + 1)
{
if (rows[i - 1][0] != 0)
summ -= j <= rows[i - 1][0] && rows[i - 1][1] <= j + k-1;
if (rows[i + k - 1][0] != 0)summ += j <= rows[i + k - 1][0] && rows[i + k - 1][1] <= j + k-1;
ans[i][j] += summ;
}
}
int tans = 0;
upd(i, 1, n)
{
upd(j, 1, n)
{
tans = max(tans, ans[i][j] + ansrow + anscol);
}
}
cout << tans << endl;
}
E题
-
拼接字符串,从左到右一次链接,每一次连接,如果当前已经连接过的字符串的后缀等于要连接的字符串的前缀,那么可以消掉。
-
直接暴力模拟即可,优化可以上kmp,不过暴力的话需要cin开ios false才行。不然会t掉。
#include<iostream>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
int read()
{
char ch = getchar(); int x = 0, f = 1;
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;
}
typedef pair<int, int> pir;
int n;
string s, ans;
int main()
{
ans = "";
ios::sync_with_stdio(false);
cin >> n;
up(i, 0, n)
{
cin >> s;
if (i == 0) { ans += s; continue; }
bool flag = 0;
int len = ans.size(), len2 = s.size();
dwd(j, len2 - 1, 0)
{
if (ans[len - 1] == s[j]&&len>=j+1)
{
int templ = len - 1; int tempj = j;
while (tempj>=0)
{
if (ans[templ] != s[tempj])break;
templ--, tempj--;
}
if (tempj == -1) {
flag = 1;
ans += s.substr(j + 1, len2 - j);
break;
}
}
}
if (!flag)ans += s;
}
cout << ans ;
}
橙橙橙