AtCoder Regular Contest 113

比賽地址c++

A(暴力)

題目連接
⭐⭐spa

題目:
給出\(K\),求出知足\(A\times B\times C\le K\)\((A,B,C)\)對數code

解析:
將C移動到等式右邊,獲得\(A\times B\le\frac{K}{C}\),對於\(t=\lfloor\frac{K}{C}\rfloor\),統計\(t\)向下整除\(1\sim t\)的和即爲結果字符串

#include<bits/stdc++.h>
using namespace std;
/*===========================================*/

int main() {
	int k;
	LL result = 0;
	scanf("%d", &k);
	for (int i = 1; i <= k; ++i) {
		int end = k / i;
		for (int j = 1; j <= end; ++j)
			result += k / i / j;
	}
	printf("%lld", result);
}

B(思惟)

題目連接
⭐⭐get

題目:
求出\(A^{B^C}\)的個位數字it

解析:
不可貴到如下循環ast

  1. 1 1 1 1 1 ...(1)
  2. 2 4 8 6 2 ...(4)
  3. 3 9 7 1 3 ...(4)
  4. 4 6 4 6 4 ...(2)
  5. 5 5 5 5 5 ...(1)
  6. 6 6 6 6 6 ...(1)
  7. 7 9 3 1 7 ...(4)
  8. 8 4 2 6 8 ...(4)
  9. 9 1 9 1 9 ...(2)
  10. 0 0 0 0 0 ...(1)
  • 對於循環長度爲1,則直接輸出自己
  • 循環長度爲2,則考慮\(B\)奇偶性(奇數的冪仍是奇數,偶數的冪仍是偶數)
  • 循環長度爲4分\(B\)的奇偶討論
    • 若是\(B\)爲奇數且模4爲1,則他的冪模4仍是1,不然模值在3 1循環
    • 若是爲偶數則必定含有2,若是能被4整除則冪數模4必定是0,不然看2(因子)的出現次數,即冪數是否大於1,比1大模值爲0,比一小模值1
#include<bits/stdc++.h>
using namespace std;
/*===========================================*/

map<int, map<int, int>> m;
int main() {
	int a, b, c;
	scanf("%d%d%d", &a, &b, &c);
	m[4][0] = 4, m[4][1] = 6;
	m[9][0] = 9, m[9][1] = 1;
	m[2][0] = 2, m[2][1] = 4, m[2][2] = 8, m[2][3] = 6;
	m[3][0] = 3, m[3][1] = 9, m[3][2] = 7, m[3][3] = 1;
	m[8][0] = 8, m[8][1] = 4, m[8][2] = 2, m[8][3] = 6;
	m[7][0] = 7, m[7][1] = 9, m[7][2] = 3, m[7][3] = 1;
	a %= 10;
	if (a == 0 || a == 1 || a == 5 || a == 6)
		printf("%d", a);
	else if (a == 4 || a == 9)
		printf("%d", m[a][b % 2 == 0]);
	else {
		if (b & 1) {
			if (b % 4 == 1)
				printf("%d", m[a][0]);
			else {
				if (c & 1)
					printf("%d", m[a][2]);
				else
					printf("%d", m[a][0]);
			}
		}
		else {
			if (b % 4 == 0)
				printf("%d", m[a][3]);
			else {
				if (c >= 2)
					printf("%d", m[a][3]);
				else
					printf("%d", m[a][1]);
			}
		}
	}
}

C(貪心)

題目連接
⭐⭐class

題目:
給出一個字符串,以及操做:若是\(s_i=s_{i+1}\ne s_{i+2}\),則將\(s_{i+2}\)替換成\(s_i\),詢問最多操做次數test

解析:
那若是又兩個連續的字符\(c\),則後序字符確定能都變成\(c\),那麼能夠考慮從後向前進行替換,這樣能夠保證最大次數
如此則須要從前向後統計第一次出現的某字符\(c\)與下一個和他不同的連續字符\(c'\)之間存在多少個\(c\)(這些字符不能夠被操做須要從答案中減去),後序字符均可以被替換,由於操做時從後向前,後序字符均會被替換成\(c'\)循環

#include<bits/stdc++.h>
typedef long long LL;
using namespace std;
/*===========================================*/

const int maxn = 2e5 + 5;
char str[maxn];

int main() {
	scanf("%s", str);
	int len = strlen(str);
	char last = 1;
	int lpos = -1;
	LL ret = 0;
	for (int i = 0; i <= len; ++i) {
		if (str[i] == str[i + 1] && str[i] != last)
		{
			if (~lpos)
				ret += 1LL * len - lpos;
			lpos = i;
			last = str[i];
		}
		if (str[i] == last)
			--ret;
	}
	printf("%lld", ret + 1);
}

D(排列組合+快速冪)

題目連接
⭐⭐⭐

題目:
給出\(n,m,k\),規定\(A_i\)爲第\(i\)行最小的數字,\(B_i\)爲第\(i\)行最大的數字,則有多少種序列的可能性(答案取模998244353)

解析:

  1. 要保證\(A\)中的最大值必定得小於等於\(B\)中最小值,由於假設A中最大值對應位置爲\((i,j)\),則在第\(j\)列的最大值要大於等於\(i\)不可能小於\(i\)
  2. 因此能夠枚舉\(i\),即\(pow(i,n)\times pow(k+1-i,m)\),可是這樣的話對於左邊(或者右邊)可能出現包含重複的狀況,因此必定要保證\(i\)\(A\)或者\(B\)序列中至少出現1次

\[\sum_{i=1}^k(i^n-(i-1)^n)*(k-i+1)^m \ \%mod \]

注意:
考慮\(n==1||m==1\)的特殊狀況

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 998244353;
LL pw(LL n, int x) {
	LL ret = 1;
	LL t = n;
	while (x) {
		if (x & 1) ret = ret * t % mod;
		t = t * t % mod;
		x >>= 1;
	}
	return ret;
}

int main() {
	int n, m, k;
	scanf("%d%d%d", &n, &m, &k);
	if (n == 1)
		printf("%lld", pw(k, m));
	else if (m == 1)
		printf("%lld", pw(k, n));
	else {
		LL ret = 0;
		for (int i = 1; i <= k; ++i)
			ret = ((pw(i, n) - pw(i - 1, n) + mod) % mod * pw(k + 1 - i, m) % mod + ret) % mod;
		printf("%lld", ret);
	}
}
相關文章
相關標籤/搜索