P3392 涂国旗
涂最少的格子(枚举)
#include <bits/stdc++.h>
using namespace std;
int n, m, ans = 1e9;
char a[55][55];
int main()
{
cin >> n >> m;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
cin >> a[i][j];
//枚举白蓝分界线和蓝红分界线位置
for(int i = 0; i < n - 2; i++){//最后两行不可能为白色
for(int j = i + 1; j < n - 1; j++){//至少最后一行为红色
int t = 0;
for(int k = 0; k <= i; k++)//前i行白
for(int l = 0; l < m; l++) if(a[k][l] != 'W') t++;
for(int k = i + 1; k <= j; k++)//i到j蓝色
for(int l = 0; l < m; l++) if(a[k][l] != 'B') t++;
for(int k = j + 1; k < n; k++)//后几行红色
for(int l = 0; l < m; l++) if(a[k][l] != 'R') t++;
ans = min(ans, t);
}
}
cout << ans << endl;
return 0;
}
P3654 First Step (ファーストステップ)
#include <bits/stdc++.h>
using namespace std;
int r, c, k, ans, tx, ty;
char m[105][105];
void dfs(int x, int y, int num, int tf){
if(num == k){ans++; return;};
if(tf == 0){//横着
tx = x + 1;
if(m[tx][y] == '.') dfs(tx, y, num + 1, 0);
}
if(tf == 1){//竖着
ty = y + 1;
if(m[x][ty] == '.') dfs(x, ty, num + 1, 1);
}
}
int main()
{
cin >> r >> c >> k;
memset(m, '#', sizeof(m));
for(int i = 1; i <= r; i++)
for(int j = 1; j <= c; j++)
cin >> m[i][j];
for(int i = 1; i <= r; i++){
for(int j = 1; j <= c; j++){
if(m[i][j] == '.'){
dfs(i, j, 1, 0);//f=0:横着
dfs(i, j, 1, 1);//f=1:竖着
}
5 }
}
if(k == 1) cout << ans / 2 << endl;//k==1时,横竖都一样
else cout << ans << endl;
return 0;
}
P1217 [USACO1.5]回文质数 Prime Palindromes
最大的回文质数是9989899;
提示 1: 找出所有的回文数再判断它们是不是质数(素数);
i%2==1时,i+奇数一定为2的倍数,因此循环可以i+=2;
#include <bits/stdc++.h>
using namespace std;
int a, b;
bool isprime(int n){
if(n == 2 || n == 3) return true;
else if(n % 6 != 1 && n % 6 != 5) return false;
else{
for(int i = 5; i * i <= n; i += 6)
if(!(n % i)||!(n % (i+2))) return false;
return true;
}
}
bool check(int n){//判断素数
int t = n, sum = 0;
while(t){
sum = sum * 10 + t % 10;
t /= 10;
}
if(sum == n) return true;
else return false;
}
int main()
{
cin >> a >> b;
if(b >= 9989899) b = 9989899;
if(a % 2 == 0) a++;
for(int i = a; i <= b; i += 2){
if(check(i) == 0) continue;
else if(isprime(i)) cout << i << endl;
}
return 0;
}
P1149 [NOIP2008 提高组] 火柴棒等式
加号与等号各自需要两根火柴棍;
如果 A !=B,则 A+B=C 与 B+A=C 视为不同的等式(A,B,C≥0);
n 根火柴棍必须全部用上。
#include <bits/stdc++.h>
using namespace std;
int n, num[10]={6, 2, 5, 5, 4, 5, 6, 3, 7, 6}, ans;
int fun(int n){
int sum = 0, i;
for(i = n; i != 0; i /= 10)
sum += num[i % 10];
if(n == 0) sum += num[0];
return sum;
}
int main()
{
cin >> n;
for(int i = 0; i <= 1000; i++)
for(int j = 0; j <= 1000; j++)
if(fun(i) + fun(j) + fun(i + j) + 4 == n) ans ++;
cout << ans << endl;
return 0;
}
P3799 妖梦拼木棒
设四个木棒长度分别为 a,b,c,d不妨设 a≤b≤c≤d。
当 a+b=c=d 的时候才能够拼成等边三角形。
即,只有四个木棒的长度分别为 a,b,a+b 和 a+b 的时候才能拼成一个等边三角形。
枚举 a,b 确定长度为 a+b 的木棒的数量numa,numb,numab
①当 a≠b时,ans += numa * numb * numab
②当 a=b时,ans += numa * (numa - 1) * numab
设a<=b, 避免重复
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n, a[100005], num[100005], ans;
ll mod = 1e9 + 7, maxa = -1;
ll C2(int n){return (n * (n - 1) / 2) % mod; }//Cn2
int main()
{
cin >> n;
for(int i = 0; i < n; i++){
cin >> a[i];
maxa = max(maxa, a[i]);
num[a[i]]++;
}//枚举a, b
for(int i = 1; i <= maxa; i++){
for(int j = i; j <= maxa; j++){// b >= a
if(i == j) ans = (ans + C2(num[i]) * C2(num[i + j])) % mod;
else ans = (ans + ((num[i] * num[j]) % mod * C2(num[i + j])) % mod) % mod;
}
} cout << ans << endl;
return 0;
}