本文是我对第十章51道习题的练习总结,建议配合紫书——《算法竞赛入门经典(第2版)》阅读本文。
先贴代码,文字性题解回头再补充。
题意
思路
代码
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define FOR1(i, a, b) for (int i = (a); i <= (int)(b); i++)
#define FOR2(i, a, b) for (int i = (a); i >= (int)(b); i--)
const int MAX = 100;
int A[10][10];
int main() {
#ifdef CODE_LIANG
freopen("datain.txt", "r", stdin);
freopen("dataout.txt", "w", stdout);
#endif
int T;
cin >> T;
FOR1(t, 1, T) {
FOR1(i, 0, 8) {
if (i & 1) continue;
FOR1(j, 0, i) {
if (j & 1) continue;
cin >> A[i][j];
}
}
FOR1(i, 0, 6) {
if (i & 1) continue;
FOR1(j, 0, i) {
if (j & 1) continue;
A[i + 2][j + 1] = (A[i][j] - A[i + 2][j] - A[i + 2][j + 2]) / 2;
A[i + 1][j] = A[i + 2][j] + A[i + 2][j + 1];
A[i + 1][j + 1] = A[i + 2][j + 1] + A[i + 2][j + 2];
}
}
FOR1(i, 0, 8) {
FOR1(j, 0, i-1) {
printf("%d ", A[i][j]);
}
printf("%d\n", A[i][i]);
}
}
return 0;
}
题意
思路
代码
题意
思路
代码
题意
思路
代码
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define FOR1(i, a, b) for (int i = (a); i <= (int)(b); i++)
#define FOR2(i, a, b) for (int i = (a); i >= (int)(b); i--)
const int MAX = 1299709+100000;//确保下一个素数被包含
int n;
int isprime[MAX];
vector prime;
void process_prime() {
memset(isprime, 0x3f, sizeof(isprime));
isprime[1] = 0;
FOR1(i, 2, MAX) {
if (isprime[i]) {
prime.push_back(i);
for (int j = i * 2; j <= MAX; j += i) {
isprime[j] = 0;
}
}
}
}
int main() {
#ifdef CODE_LIANG
freopen("datain.txt", "r", stdin);
freopen("dataout.txt", "w", stdout);
#endif
process_prime();
while (cin >> n && n) {
if (isprime[n]) {
printf("0\n", n);
continue;
}
int s = prime.size();
FOR1(i, 0, s - 1) {
if (prime[i] > n) {
printf("%d\n", prime[i] - prime[i - 1]);
break;
}
}
}
return 0;
}
题意
思路
代码
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define FOR1(i, a, b) for (int i = (a); i <= (int)(b); i++)
#define FOR2(i, a, b) for (int i = (a); i >= (int)(b); i--)
const int MAXN = 1120;
const int MAXP = 187; //计算得出最多有187个素数
const int MAXK = 14; //计算得出最多有187个素数
int n, k, ans;
int isprime[MAXN+1];
vector prime;
//int dp[MAXP + 1][MAXK + 1][MAXN + 1]; //dp[i][j][m]表示前i个素数中挑出j个素数其值为m的可能数,实际上第一维可以省略
int dp[MAXK + 1][MAXN + 1]; //dp[j][m]表示前i个素数中挑出j个素数其值为m的可能数,第一维已经省略
void process_prime() {
memset(isprime, 0x3f, sizeof(isprime));
isprime[1] = 0;
FOR1(i, 2, MAXN) {
if (isprime[i]) {
prime.push_back(i);
for (int j = i * 2; j <= MAXN; j += i) {
isprime[j] = 0;
}
}
}
}
int main() {
#ifdef CODE_LIANG
freopen("datain.txt", "r", stdin);
freopen("dataout.txt", "w", stdout);
#endif
process_prime();
while (cin >> n >> k && n) {
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
FOR1(i, 1, MAXP) {
if (prime[i-1] > n) break;
int pi = prime[i-1];
FOR2(j, min(i, k), 1) {
FOR2(m, n, pi) {
dp[j][m] += dp[j - 1][m - pi];
}
}
}
printf("%d\n", dp[k][n]);
}
return 0;
}
题意
思路
代码
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define FOR1(i, a, b) for (int i = (a); i <= (int)(b); i++)
#define FOR2(i, a, b) for (int i = (a); i >= (int)(b); i--)
const int MAX = 10000;//确保下一个素数被包含
int n, p; //p表示prime中素数个数
int isprime[MAX + 1];
vector prime;
void process_prime() {
memset(isprime, 0x3f, sizeof(isprime));
isprime[1] = 0;
FOR1(i, 2, MAX) {
if (isprime[i]) {
prime.push_back(i);
for (int j = i * 2; j <= MAX; j += i) {
isprime[j] = 0;
}
}
}
p = prime.size();
}
int main() {
#ifdef CODE_LIANG
freopen("datain.txt", "r", stdin);
freopen("dataout.txt", "w", stdout);
#endif
process_prime();
while (cin >> n && n) {
int res = 0;
int i = 0, j = 0;
int s = prime[0];
while (j < p) {
if (s == n) {
res++;
if (j == p - 1) break;
s += prime[++j];
}
else if (s < n) {
if (j == p - 1) break;
s += prime[++j];
}
else {
if (i == p - 1) break;
s -= prime[i++];
if (i > j)
s += prime[++j];
}
}
printf("%d\n", res);
}
return 0;
}
题意
思路
代码
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
#define FOR1(i, a, b) for (int i = (a); i <= (int)(b); i++)
#define FOR2(i, a, b) for (int i = (a); i >= (int)(b); i--)
const LL MAX = 1000000;
const LL LMAX = MAX*MAX;
LL a[2];
int p; //p表示oneprime中素数个数
int isprime[MAX + 1];
vector oneprime;
void process_prime() {
memset(isprime, 0x3f, sizeof(isprime));
isprime[1] = 0;
FOR1(i, 2, MAX) {
if (isprime[i]) {
for (LL j = (LL)i * i; j <= LMAX; j *= i)
oneprime.push_back(j);
for (int j = i * 2; j <= MAX; j += i) {
isprime[j] = 0;
}
}
}
sort(oneprime.begin(), oneprime.end());
p = oneprime.size();
}
int main() {
#ifdef CODE_LIANG
freopen("datain.txt", "r", stdin);
freopen("dataout.txt", "w", stdout);
#endif
process_prime();
int T;
cin >> T;
FOR1(t, 1, T) {
cin >> a[0] >> a[1];
a[1]++;
int res[2];
FOR1(j, 0, 1) {
FOR1(i, 0, p - 1) {
if (oneprime[i] >= a[j]) {
res[j] = i;
break;
}
}
}
printf("%d\n", res[1] - res[0]);
}
return 0;
}
题意
思路
代码
#include
#include
#include
#include
#include
#include
#include
#include
题意
思路
代码
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define FOR1(i, a, b) for (int i = (a); i <= (int)(b); i++)
#define FOR2(i, a, b) for (int i = (a); i >= (int)(b); i--)
//const int MAXN2 = 1e9;
const int MAXN = 40000;
int L, U;
int isprime[MAXN+1];
vector prime;
int resn, resi;
void process_prime() {
memset(isprime, 0x3f, sizeof(isprime));
isprime[1] = 0;
FOR1(i, 2, MAXN) {
if (isprime[i]) {
prime.push_back(i);
for (int j = i * 2; j <= MAXN; j += i) {
isprime[j] = 0;
}
}
}
}
int main() {
#ifdef CODE_LIANG
freopen("datain.txt", "r", stdin);
freopen("dataout.txt", "w", stdout);
#endif
process_prime();
int T;
cin >> T;
FOR1(t, 1, T) {
cin >> L >> U;
resn = L, resi = 0;
FOR1(k, L, U) {
int k1 = k;
int ik = k1 - L;
int res = 1;
int k2 = sqrt(k1) + 1;
int pcnt = prime.size();
FOR1(j, 0, pcnt-1) {
int mult = 1;
int pj = prime[j];
if (k1 == 1) break;
while (k1 % pj == 0) {
k1 /= pj;
mult++;
}
res *= mult;
}
if (k1 > 1) //说明还有约数
res *= 2;
if (res > resi) {
resn = k;
resi = res;
}
}
printf("Between %d and %d, %d has a maximum of %d divisors.\n", L, U, resn, resi);
}
return 0;
}
题意
思路
代码
题意
思路
代码
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define FOR1(i, a, b) for (int i = (a); i <= (int)(b); i++)
#define FOR2(i, a, b) for (int i = (a); i >= (int)(b); i--)
const int MAXN = 10000;
int n;
string s[3];
string add(string s1, string s2) {
string sum;
int up = 0;
int l1 = s1.size(), l2 = s2.size();
FOR1(i, 0, MAXN) {
if (i >= l1 && i >= l2) {
if (up) sum += (char)(up + 48);
break;
}
int a1 = (i < l1) ? s1[i]-48 : 0;
int a2 = (i < l2) ? s2[i]-48 : 0;
up = up + a1 + a2;
sum += (char)(up % 10 + 48);
up /= 10;
}
return sum;
}
int main() {
#ifdef CODE_LIANG
freopen("datain.txt", "r", stdin);
freopen("dataout.txt", "w", stdout);
#endif
while (cin >> n) {
s[1] = "1";
s[2] = "2";
FOR1(i, 0, n - 3) {
s[0] = s[1];
s[1] = s[2];
s[2] = add(s[0], s[1]);
}
s[1] = add(s[0], s[2]);
int scnt = s[1].size();
FOR2(i, scnt - 1, 0)
printf("%c", s[1][i]);
printf("\n");
}
return 0;
}
题意
思路
代码
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define FOR1(i, a, b) for (int i = (a); i <= (int)(b); i++)
#define FOR2(i, a, b) for (int i = (a); i >= (int)(b); i--)
const int MAXN = 50000;
int n;
double F[MAXN + 1];
void pre_process() {
F[1] = 1;
F[2] = 0.5;
FOR1(i, 2, MAXN - 1)
F[i + 1] = F[i] * (2 * i - 1) / 2 / i;
}
int main() {
#ifdef CODE_LIANG
freopen("datain.txt", "r", stdin);
freopen("dataout.txt", "w", stdout);
#endif
pre_process();
int T;
cin >> T;
FOR1(t, 1, T) {
cin >> n;
printf("%.4lf\n", 1 - F[n / 2]);
}
return 0;
}
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define FOR1(i, a, b) for (int i = (a); i <= (int)(b); i++)
#define FOR2(i, a, b) for (int i = (a); i >= (int)(b); i--)
const int MAXN = 1000;
int n;
string S[1001];
string add(string s1, string s2) {
string sum;
int up = 0;
int l1 = s1.size(), l2 = s2.size();
FOR1(i, 0, MAXN) {
if (i >= l1 && i >= l2) {
if (up) sum += (char)(up + 48);
break;
}
int a1 = (i < l1) ? s1[i] - 48 : 0;
int a2 = (i < l2) ? s2[i] - 48 : 0;
up = up + a1 + a2;
sum += (char)(up % 10 + 48);
up /= 10;
}
return sum;
}
void pre_process() {
S[1] = "0";
S[2] = "1";
S[3] = "1";
FOR1(i, 4, MAXN)
S[i] = add(S[i-2], add(S[i-1], S[i-2]));
}
int main() {
#ifdef CODE_LIANG
freopen("datain.txt", "r", stdin);
freopen("dataout.txt", "w", stdout);
#endif
pre_process();
while (cin >> n) {
int scnt = S[n].size();
FOR2(i, scnt - 1, 0)
printf("%c", S[n][i]);
printf("\n");
}
return 0;
}
题意
思路
代码
#include
#include
#include
using namespace std;
const int N = 1000001;
bool isPrime[N+1];
bool isSemi[N+1];
int countSemi[N/4+1];
void initPrime()
{
int i;
for (i = 0; i <= N; i ++)
isPrime[i] = true;
isPrime[0] = isPrime[1] = false;
for (i = 5; i <= N; i += 4) {
if (isPrime[i]) {
if (i > (int)sqrt((double)N)) continue;
for (int j = i*i; j <= N; j += 4*i)
isPrime[j] = false;
}
}
}
void initSemi()
{
int i, j;
for (i = 1; i <= N; i += 4) {
isSemi[i] = false;
countSemi[i/4] = 0;
}
for (i = 5; i <= N; i += 4) {
if (i > (int)sqrt((double)N)) break;
for (j = i; j <= N; j += 4) {
if (i * j > N) break;
if (isPrime[i] && isPrime[j])
isSemi[i * j] = true;
}
}
for (i = 5; i <= N; i += 4) {
countSemi[i/4] = countSemi[i/4-1];
if (isSemi[i])
countSemi[i/4] ++;
}
}
int main(void)
{
int n;
initPrime();
initSemi();
while (cin >> n && n) {
printf("%d %d\n", n, countSemi[n/4]);
}
return 0;
}
题意
思路
代码
题意
思路
代码
题意
思路
代码
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define FOR1(i, a, b) for (int i = (a); i <= (int)(b); i++)
#define FOR2(i, a, b) for (int i = (a); i >= (int)(b); i--)
const int MAXM = 2000;
int n, m;
int u[MAXM], d[MAXM];
int main() {
#ifdef CODE_LIANG
freopen("datain.txt", "r", stdin);
freopen("dataout.txt", "w", stdout);
#endif
while (cin >> n >> m) {
int ans = -1, minfloor = 0x3f3f3f3f;
FOR1(i, 0, m - 1) {
cin >> u[i] >> d[i];
int floor = (n*u[i]) - (n*u[i] - 1) / (u[i] + d[i]) * (u[i] + d[i]);
if (floor < minfloor) {
ans = i;
minfloor = floor;
}
}
printf("%d\n", minfloor);
}
return 0;
}
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码
题意
思路
代码