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 ;
    }
posted @ 2019-08-12 18:02  LORDXX  阅读(93)  评论(0编辑  收藏  举报