素数
Summation of Four Primes
UVa 10168
把一个数拆分成四个素数。可以把一个数
n
n
n拆为
2
+
2
+
n
−
4
2+2+n-4
2+2+n−4或
2
+
2
+
n
−
5
2+2+n-5
2+2+n−5,然后对剩下的偶数使用哥德巴赫猜想即可。
#include<bits/stdc++.h>
#define ll long long
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define INF 0x3f3f3f3f
const int N = 1e7 + 10;
const int mod = 1e9 + 7;
ll gcd(ll p, ll q) { return q == 0 ? p : gcd(q, p % q); }
using namespace std;
int n;
int prime[N];
bool is_prime[N];
int sieve() {
int p = 0;
for (int i = 0; i <= N; ++i)
is_prime[i] = true;
is_prime[0] = is_prime[1] = false;
for (int i = 2; i <= N; ++i) {
if (is_prime[i]) {
prime[p++] = i;
for (int j = i + i; j <= N; j += i)
is_prime[j] = false;
}
}
return p;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int tot = sieve();
while (cin >> n && n) {
if(n<8) {
printf("Impossible.\n");
continue;
}
if(n&1) {
printf("2 3 ");
n-=5;
}
else {
printf("2 2 ");
n-=4;
}
for (int i = 0; i < tot && 2 * prime[i] <= n; i++)
if (is_prime[n - prime[i]]) {
printf("%d %d\n",prime[i],n-prime[i]);
break;
}
}
return 0;
}
扩展欧几里得
One Person Game
ZOJ 3593
在数轴上,需要从A到B,每次可以向左或向右走
a
、
b
、
a
+
b
a、b、a+b
a、b、a+b,求最小的步数。
【侯山窝矿工】ZOJ 3593 One Person Game 扩展欧几里得
The Balance
POJ 2142
给两种砝码和一个物品的质量,求使天平平衡的最少砝码数。
也就是求
∣
x
∣
+
∣
y
∣
\vert x\vert+\vert y\vert
∣x∣+∣y∣的最小值,分别求一次
x
x
x、
y
y
y即可。
#include<bits/stdc++.h>
#define ll long long
ll gcd(ll p, ll q) { return q == 0 ? p : gcd(q, p % q); }
using namespace std;
const int N = 1e6 + 10;
typedef std::pair<int, int> pii;
ll x,y;
ll exgcd(ll a, ll b, ll &x, ll &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
ll r = exgcd(b, a % b, y, x);
y -= x * (a / b);
return r;
}
int main() {
int a, b, d;
while (cin >> a >> b >> d) {
if (!a && !b && !d) break;
ll e = gcd(a,b);
a/=e;
b/=e;
exgcd(a,b,x,y);
ll x0=x*(d/e) % b;
if(x0<0) x0 = (x0+b)%b;
ll y0 = (d/e - a*x0)/b;
if(y0<0) y0=-y0;
ll y1=y*(d/e) % a;
if(y1<0) y1 = (y1+a)%a;
ll x1 = (d/e - b*y1)/a;
if(x1<0) x1=-x1;
if(x1+y1<x0+y0) cout<<x1<<' '<<y1<<endl;
else cout<<x0<<' '<<y0<<endl;
}
return 0;
}