1. 程式人生 > >[題解][Codeforces 1080A~1080F]Codeforces Round #524 簡要題解

[題解][Codeforces 1080A~1080F]Codeforces Round #524 簡要題解

引入

  • 人生第一次 CF
  • 也是難得的一次時間在下午的比賽
  • 在讀題上浪費了好多時間,藥丸
  • 因為不熟悉賽制, D 題不檢查就提交
  • 結果 WA 了兩發

題目

洛谷 RemoteJudge

Codeforces

A

題意

  • 給定 n n
    k k
  • n n 個人,每個人需要 2
    2
    張紅紙, 5 5 張綠紙, 8 8 張藍紙
  • 需要買一些紙,但一次必須買一堆 k
    k
    張同色的紙
  • 求至少需要買幾堆紙
  • 1 n , k 1 0 8 1\le n,k\le 10^8

題解

  • 本題的主要難點在理解英文題目
  • 2 n k + 5 n k + 8 n k \lceil\frac{2n}k\rceil+\lceil\frac{5n}k\rceil+\lceil\frac{8n}k\rceil

程式碼

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

int n, k;

int main()
{
	std::cin >> n >> k;
	std::cout << (2 * n + k - 1) / k + (5 * n + k - 1) / k
		+ (8 * n + k - 1) / k << std::endl;
	return 0;
}

B

題意

  • 給定一個數列 a a ,滿足 a i = i × ( 1 ) i a_i=i\times(-1)^i
  • q q 組詢問
  • 每次詢問 i = l r a i \sum_{i=l}^ra_i
  • 1 q 1 0 3 1\le q\le 10^3 1 l r 1 0 9 1\le l\le r\le 10^9

題解

  • 如果 r l + 1 r-l+1 是奇數,就直接轉化成區間 [ l , r 1 ] [l,r-1] 的和再加上 a r a_r ,顯然區間 [ l , r 1 ] [l,r-1] 的長度是偶數
  • 如果區間長度 r l + 1 r-l+1 是偶數,那麼
  • (1) l l 是奇數時區間和為 r l + 1 2 \frac{r-l+1}2
  • (2) l l 是偶數時區間和為 r l + 1 2 -\frac{r-l+1}2

程式碼

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

inline int read()
{
	int res = 0; bool bo = 0; char c;
	while (((c = getchar()) < '0' || c > '9') && c != '-');
	if (c == '-') bo = 1; else res = c - 48;
	while ((c = getchar()) >= '0' && c <= '9')
		res = (res << 3) + (res << 1) + (c - 48);
	return bo ? ~res + 1 : res;
}

int q;

int main()
{
	int l, r;
	q = read();
	while (q--)
	{
		l = read(); r = read();
		int res = l & 1 ? r - l + 1 >> 1 : - (r - l + 1 >> 1);
		if (!(r - l & 1))
		{
			if (r & 1) res -= r;
			else res += r;
		}
		printf("%d\n", res);
	}
	return 0;
}

C

題意

  • 給定一個 n × m n\times m 的網格,對於第 i i 行第 j j 列,如果 i + j i+j 為偶數則 ( i , j ) (i,j) 為白色,否則為黑色
  • 進行兩次操作
  • 第一次把一個子矩形全部染黑
  • 第二次把一個子矩形全部染白
  • 最後求棋盤上白、黑的格子數
  • 多組資料(不超過 1 0 3 10^3 組), 1 n , m 1 0 9 1\le n,m\le 10^9

題解

  • 操作之前一個子矩形的黑白格子數很容易計算
  • 如果格子數為偶數,則黑白格子各佔一半
  • 否則與這個子矩形的左下角的顏色同色的格子數是該子矩形總格子數除以二後上取整
  • 將兩個子矩形分開處理即可
  • 如果兩個子矩形有交則需要處理相交部分,可以利用容斥的思想

程式碼

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

inline int read()
{
	int res = 0; bool bo = 0; char c;
	while (((c = getchar()) < '0' || c > '9') && c != '-');
	if (c == '-') bo = 1; else res = c - 48;
	while ((c = getchar()) >= '0' && c <= '9')
		res = (res << 3) + (res << 1) + (c - 48);
	return bo ? ~res + 1 : res;
}

template <class T>
inline T Min(const T &a, const T &b) {return a < b ? a : b;}

template <class T>
inline T Max(const T &a, const T &b) {return a > b ? a : b;}

typedef long long ll;

int n, m, X1, Y1, X2, Y2, X3, Y3, X4, Y4;
ll w, b;

ll rects(int xl, int yl, int xr, int yr)
{
	if (!(1ll * (xr - xl + 1) * (yr - yl + 1) & 1))
		return 1ll * (xr - xl + 1) * (yr - yl + 1) >> 1;
	if (xl + yl & 1) return 1ll * (xr - xl + 1) * (yr - yl + 1) >> 1;
	return (1ll * (xr - xl + 1) * (yr - yl + 1) >> 1) + 1;
}

ll stcer(int xl, int yl, int xr, int yr)
{
	return 1ll * (xr - xl + 1) * (yr - yl + 1) - rects(xl, yl, xr, yr);
}

void work()
{
	n = read(); m = read();
	X1 = read