统计方形加强版题目描述
#include
#include
using namespace std;
typedef long long ll;
int main() {
ll n, m, squ = 0, rec = 0;
scanf("%lld%lld", &n, &m);
for(ll x = 0; x <= n; x++)
for(ll y = 0; y <= m; y++) {
ll tmp = min(x, y); //统计左上角斜线的格点
squ += tmp;
rec += x * y - tmp;
}
printf("%lld %lld", squ, rec);
return 0;
}
三连击升级版 题目描述
//方法1
//通过枚举一个3位来确定另外两个3位
#include
#include
#include
#include
using namespace std;
int b[10];
void go(int x) {
b[x % 10] = 1;
b[x / 10 % 10] = 1;
b[x / 100] = 1;
}
bool check(int x, int y, int z) {
memset(b, 0, sizeof(b));
if(y > 999 || z > 999) return 0;
go(x), go(y), go(z);
for(int i = 1; i <= 9; i++)
if(!b[i]) return 0;
return 1;
}
int main() {
long long a, b, c, x, y, z, cnt = 0;
cin >> a >> b >> c;
for(x = 123; x <= 987; x++) {
if(x * b % a && x * c % a) continue;
y = x * b / a, z = x * c / a;
if(check(x, y, z))
printf("%lld %lld %lld\n", x, y, z), cnt++;
}
if(!cnt) cout << "No!!!" << endl;
return 0;
}
//方法2
//使用next_permutation(start, end)产生下一个字典序排列
#include
#include
#include
using namespace std;
typedef long long ll;
int w[10];
int main() {
ll a, b, c, x, y, z, cnt = 0;
cin >> a >> b >> c;
for(int i = 1; i <= 9; i++) w[i] = i;
do {
x = w[1] * 100 + w[2] * 10 + w[3];
y = w[4] * 100 + w[5] * 10 + w[6];
z = w[7] * 100 + w[8] * 10 + w[9];
if(x * b == y * a && y * c == z * b)
printf("%lld %lld %lld\n", x, y, z), cnt++;
} while(next_permutation(w+1, w+10));
if(!cnt) cout << "No!!!" << endl;
return 0;
}
选数题目描述
//方法1
#include
#include
using namespace std;
int a[30];
bool check(int x) { //判断质数
for(int i = 2; i * i <= x; i++)
if(x % i == 0) return 0;
return 1;
}
int main() {
int n, k, ans = 0;
cin >> n >> k;
for(int i = 0; i < n; i++) scanf("%d", &a[i]);
int u = 1 << n; //全集
for(int s = 0; s < u; s++) //枚举所有子集[0, u)
/*
1 __builtin_popcount()返回一个数二进制下1的个数
2 a<>n等于a整除2的n次方
*/
if(__builtin_popcount(s) == k) { //找到k元子集
int sum = 0;
for(int i = 0; i < n; i++)
if(s & (1 << i)) sum += a[i]; //如果第i个元素在s中
if(check(sum)) ans++;
}
cout << ans;
return 0;
}
//方法2
#include
#include
using namespace std;
int x[20], n, k;
bool isprime(int n){ //判断是否质数
int s = sqrt(double(n));
for(int i = 2; i <= s; i++)
if(n % i == 0) return false;
return true;
}
int rule(int left_num, int a_sum, int start, int end){
/*
left_num为剩余的k,alr_sum为前面累加的和
start和end为全组合剩下数字的选取范围;调用递归生成全组合,在过程中逐渐把K个数相加
当选取的数个数为0时,直接返回前面的累加和是否为质数即可
*/
if(left_num == 0) return isprime(a_sum);
int sum = 0;
for(int i = start; i <= end; i++)
sum += rule(left_num - 1, a_sum + x[i], i + 1, end);
return sum;
}
int main(){
cin >> n >> k;
for(int i = 0; i < n; i++) cin >> x[i];
cout << rule(k, 0, 0, n - 1); //调用递归解决问题
}
组合的输出题目描述
//从高位到低位表示,可以让1尽量出现在靠前位置
#include
#include
using namespace std;
int a[30];
int main() {
int n, r;
cin >> n >> r;
for(int s = (1 << n) - 1; s >= 0; s--) {
int cnt = 0;
for(int i = 0; i < n; i++)
if(s & (1 << i)) a[cnt++] = i;
if(cnt == r) {
for(int i = r - 1; i >= 0; i--)
printf("%3d", n - a[i]);
cout << endl;
}
}
return 0;
}
火柴棒等式题目描述
#include
using namespace std;
int c[10] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6};
int main() {
int a[2001] = {6}, b, s = 0, i, j;
scanf("%d", &b);
for(i = 1; i <= 2000; i++) {
j = i;
while(j > 0) { //求每个数所用的火柴棒
a[i] += c[j%10];
j /= 10;
}
}
for(i = 0; i <= 1000; i++) {
for(j = 0; j <= 1000; j++)
if(a[i] + a[j] + a[i+j] + 4 == b) s++; //还有加号与等号
}
printf("%d", s);
return 0;
}
妖梦拼木棒题目描述
#include
#include
using namespace std;
const int kMaxn = 1e5 + 10;
const int kMod = 1e9 + 7;
long long count = 0;
long long f(int q) { //求组合数,在q里面选2个
return (q - 1) * q / 2;
}
int main() {
int maxlen = 2, n, a[kMaxn], x;
cin >> n;
for(int i = 0; i < n; i++) {
cin >> x;
a[x]++;
if(x > maxlen) maxlen = x;
}
for(int i = 2; i <= maxlen; i++)
if(a[i] >= 2)
for(int j = 1; j < i / 2 + 1; j++)
if((i - j) != j)
count += a[j] * a[i - j] * f(a[i]);
else if ((i - j) == j && a[j] >= 2)
count += f(a[i]) * f(a[j]);
cout << count % kMod << endl;
return 0;
}
回文质数题目描述
#include
#include
#define MAXN 10000005 //偶数位数回文数(除11)必定不是质数,所以只要运行到10000000。
using namespace std;
int prime[MAXN];
bool pd_h(int x) {
int y = x, num = 0; //int y=x,防止x被改变
while (y != 0) {
num = num * 10 + y % 10; //上一次数字的记录进位再加上下一位数
y /= 10;
}
if (num == x) return 1;
else return 0;
}
int main() {
int a, b;
cin >> a >> b;
int cnt = 0;
if(b > 10000000) b = 10000000;
for (int i = 0; i < MAXN; i++) prime[i] = 1; //先把每个数都定义为合数
for (int i = 2; i < MAXN; i++) {
if (!prime[i]) continue;
for (int j = i * 2; j < MAXN; j+=i) prime[j] = 0; //将i的倍数标记为合数
}
for(int i = a; i <= b; i++) {
if(i > 10000000) break;
if(pd_h(i) && prime[i]) printf("%d\n", i);
}
}
报数题目描述
#include
using namespace std;
const int INF = 1e7 + 10;
int vis[INF], vk[INF];
mapkv;
int main() {
int t, x, k = 1;
for(int i = 1; i < INF; i++) {
int c = i;
if(!vis[i])
while(c) {
if(c % 10 == 7) {
for(int j = 1; j * i < INF; j++) vis[i * j] = true;
break;
}
c /= 10;
}
if(!vis[i]) {
kv[i] = k, vk[k] = i, k++;
}
}
cin >> t;
while(t--) {
cin >> x;
if(vis[x]) cout << -1 << endl;
else cout << vk[kv[x] + 1] << endl;
}
return 0;
}