题目分析
暴力美学专题
A:可以枚举区间[i, j] ,枚举区间的复杂度是O(n*n*n)
#include <cstdio>
typedef long long ll;
ll num[25];
char str[25];
int main(){
int n;
int t = 1;
while(scanf("%d", &n) != EOF){
for(int i = 0; i < n; ++i) scanf("%lld", num+i);
ll maxn = -1e18 - 10;
for(int i = 0; i < n; ++i)
for(int j = i; j < n; ++j){
ll sum = 1;
for(int k = i; k <= j; ++k)
sum *= num[k];
if(sum > maxn) maxn = sum;
}
printf("Case #%d: The maximum product is %lld.\n\n", t++, maxn<0?0:maxn);
}
return 0;
}
B:暴力即可,加些技巧可简短代码长度
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int qq = (1<<10) + 10;
int tot, n;
int vis[15];
struct Num{
int x, y;
bool operator < (const Num &a)const{
return y < a.y;
}
}num[qq];
bool judge(int x){
int flag[11];
memset(flag, 0, sizeof(flag));
int y = x / n;
if(x < 10000) flag[0] = 1;
while(x){
flag[x%10] = 1;
x /= 10;
}
if(y < 10000 && y > 1000){
if(flag[0]) return false;
else flag[0] = 1;
}else if(y < 1000) return false;
while(y){
if(flag[y%10]) return false;
flag[y%10] = 1;
y /= 10;
}
return true;
}
int main(){
int t = 0;
while(scanf("%d", &n)==1 && n){
memset(vis, 0, sizeof(vis));
tot = 0;
if(t) puts("");
int cnt = 0;
for(int i,j,k,l,m = 0; m < 10; ++m){
vis[m] = 1;
for(l = 0; l < 10; ++l){
if(vis[l]) continue;
vis[l] = 1;
for(k = 0; k < 10; ++k){
if(vis[k]) continue;
vis[k] = 1;
for(j = 0; j < 10; ++j){
if(vis[j]) continue;
vis[j] = 1;
for(i = 0; i < 10; ++i){
if(vis[i]) continue;
int res = m*10000+l*1000+k*100+j*10+i;
//printf("%d\n", res);
//if(res == 96270) printf("111\n");
if(res % n == 0 && judge(res)){
num[tot].x = res;
num[tot++].y = res/n;
cnt++;
}
}
vis[j] = 0;
}
vis[k] = 0;
}
vis[l] = 0;
}
vis[m] = 0;
}
if(!cnt) printf("There are no solutions for %d.\n", n);
sort(num, num+tot);
for(int i = 0; i < tot; ++i)
printf("%05d / %05d = %d\n", num[i].x, num[i].y, n);
t++;
}
return 0;
}
C:先把n + n以内的素数求出来,然后dfs从小到大去加数判断即可,注意最后要判断一下首尾
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cctype>
using namespace std;
const int qq = 50;
int prim[qq];
int n;
int num[qq];
int vis[qq];
void dfs(int cnt){
if(cnt == n){
if(!prim[num[0]+num[n-1]]){
for(int i = 0; i < n-1; ++i)
printf("%d ", num[i]);
printf("%d\n", num[n-1]);
}
return;
}
for(int i = 1; i <= n; ++i){
if(vis[i]) continue;
if(prim[num[cnt-1]+i]) continue;
vis[i] = 1;
num[cnt] = i;
dfs(cnt+1);
vis[i] = 0;
}
}
int main(){
memset(prim, 0, sizeof(prim));
prim[1] = 1;
for(int i = 2; i < qq; ++i)
for(int j = i+i; j < qq; j += i)
prim[j] = 1;
int t = 1;
while(scanf("%d", &n) != EOF){
if(t != 1)
printf("\n");
printf("Case %d:\n", t++);
memset(vis, 0, sizeof(vis));
vis[1] = 1;
num[0] = 1;
dfs(1);
}
return 0;
}
D:一道简单的树形结构题,从根节点一直向下dfs然后在搜索的过程都更新当前节点到根节点的距离即可,最后找一下每个节点到根节点的最大距离,存图需要用邻接表,这里用vector实现(推荐用静态链表(链式前向星))
PS:一般情况下vector的获得内存空间的实现要看评测既是否开了O2优化,开了的话能大大提高cache的命中率,从而提升使用vector的效率,如果没开O2的话很多情况下使用vector会超时
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <utility>
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define REP(i, x, n) for(int i = x; i < n; ++i)
const int qq = 1e5 + 10;
vector<int> vt[qq],dist[qq];
LL dp[qq];
int n;
LL m;
void dfs(int u, LL w){
dp[u] = w;
int sz = (int)vt[u].size();
for(int j = 0; j < sz; ++j){
dfs(vt[u][j], w + dist[u][j]);
}
}
int main(){
int t; cin >> t;
while(t--){
memset(dp, 0, sizeof(dp));
scanf("%d%lld", &n, &m);
for(int i = 0; i < n - 1; ++i){
int a, b, c; scanf("%d%d%d", &a, &b, &c);
vt[a].pb(b), dist[a].pb(c);
}
dfs(1, 0);
LL maxn = -1;
for(int i = 1; i <= n; ++i)
maxn = max(maxn, dp[i]);
if(maxn < m) printf("-1\n");
else printf("%lld\n", maxn);
for(int i = 0; i <= n; ++i)
vt[i].clear(), dist[i].clear();
}
return 0;
}
E:首先要明确,你要得到某个颜色一定是这个生物去吞噬了其他所有生物(或者其他生物吞噬其他生物,但是最终被这个颜色的生物吞噬了),这题是基于贪心的想法,先把生物的尺寸大小从大到小排序,用num[i]代表第i位置上生物的大小,sum[i]代表从i开始包括i到最后一个生物尺寸大小的和,那么如果存在某个 (num[i] + sum[i + 1])* 2 〈 num[i - 1], 那么之后的所有生物的颜色都不能得到了。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <sstream>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define REP(i, x, n) for(int i = x; i < n; ++i)
const int qq = 1e5 + 10;
int n;
LL sum[qq], num[qq];
bool cmp(LL a, LL b){
return a > b;
}
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
scanf("%lld", num + i);
sort(num + 1, num + 1 + n, cmp);
for(int i = n; i >= 1; --i)
sum[i] = sum[i + 1] + num[i];
int res = 1;
for(int i = 2; i <= n; ++i)
if((LL)2 * (num[i] + sum[i + 1]) >= num[i - 1]) res++;
else{
break;
}
printf("%d\n", res);
return 0;
}
F:暴力打表或者递归求解都可
#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
#define LL long long
#define REP(i, x, n) for(int i = x; i < n; ++i)
#define mst(Arr, x) memset(Arr, x, sizeof(Arr))
const int qq = 23;
LL W[qq][qq][qq];
int a, b, c;
LL Dfs(int a, int b, int c){
if(a <= 0 || b <= 0 || c <= 0) return 1;
if(a > 20 || b > 20 || c > 20){
if(W[20][20][20] != -1) return W[20][20][20];
else return Dfs(20, 20, 20);
}
if(W[a][b][c] != -1) return W[a][b][c];
if(a < b && b < c)
return W[a][b][c] = Dfs(a, b, c - 1) + Dfs(a, b - 1, c - 1) - Dfs(a, b - 1, c);
return W[a][b][c] = Dfs(a - 1, b, c) + Dfs(a - 1, b - 1, c) + Dfs(a - 1, b, c - 1) - Dfs(a - 1, b -1 , c - 1);
}
int main(){
while(scanf("%d%d%d", &a, &b, &c) != EOF){
mst(W, -1);
if(a == -1 && b == -1 && c == -1) break;
printf("w(%d, %d, %d) = %lld\n", a, b, c, Dfs(a, b, c));
}
return 0;
}
G:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define LL long long
#define REP(i, x, n) for(int i = 0; i < n; ++i)
#define mst(Arr, x) memset(Arr, x, sizeof(Arr))
#define pb push_back
const int qq = 23;
int C[qq][qq];
int vis[qq];
int n, maxn;
void Dfs(int u){
if(u > n){
int sum = 0;
for(int i = 1; i <= n; ++i)
if(vis[i]){
for(int j = 1; j <= n; ++j)
if(!vis[j]) sum += C[i][j];
}
maxn = max(maxn, sum);
return;
}
vis[u] = 1;
Dfs(u + 1);
vis[u] = 0;
Dfs(u + 1);
}
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j)
scanf("%d", &C[i][j]);
maxn = -1;
mst(vis, 0);
Dfs(1);
printf("%d\n", maxn);
return 0;
}
H题:二进制枚举搜索都可
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cctype>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
using namespace std;
#define REP(i, x, n) for(int i = x; i < n; ++i)
const int qq = 6;
char gra[qq][qq], tmp[qq][qq];
int num[qq];
int n;
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
bool isboard(int x, int y){
if(x < 1 || y < 1 || x > n || y > n) return false;
return true;
}
int check(){
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j)
tmp[i][j] = gra[i][j];
for(int col = 1; col <= n; ++col){
for(int i = 0; i < n; ++i)
if(num[col] & (1 << i)){
if(tmp[col][i + 1] == 'X') continue;
tmp[col][i + 1] = '1';
}
}
int cnt = 0;
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j){
if(tmp[i][j] == '1'){
for(int k = 0; k < 4; ++k){
int x = i + dx[k], y = j + dy[k];
bool flag = true;
while(1){
if(!isboard(x, y)) break;
if(tmp[x][y] == 'X') break;
if(tmp[x][y] == '1'){
flag = false;
break;
}
x = x + dx[k];
y = y + dy[k];
}
if(!flag) return false;
}
++cnt;
}
}
return cnt;
}
int main(){
while(scanf("%d", &n) != EOF){
if(!n) break;
for(int i = 1; i <= n; ++i)
scanf("%s", gra[i] + 1);
int ans = 0;
if(n == 4){
for(int l, k, j, i = 0; i < (1 << n); ++i)
for(j = 0; j < (1 << n); ++j)
for(k = 0; k < (1 << n); ++k)
for(l = 0; l < (1 << n); ++l){
num[1] = i, num[2] = j, num[3] = k, num[4] = l;
ans = max(check(), ans);
}
}else if(n == 3){
for(int k, j, i = 0; i < (1 << n); ++i)
for(j = 0; j < (1 << n); ++j)
for(k = 0; k < (1 << n); ++k){
num[1] = i, num[2] = j, num[3] = k;
ans = max(check(), ans);
}
}else if(n == 2){
for(int j, i = 0; i < (1 << n); ++i)
for(j = 0; j < (1 << n); ++j){
num[1] = i, num[2] = j;
ans = max(check(), ans);
}
}else{
if(gra[1][1] == '.') ans = 1;
}
printf("%d\n", ans);
}
return 0;
}
I:思维题,需要分情况讨论,然后推公式
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cctype>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <utility>
using namespace std;
#define pb push_back
#define mk make_pair
#define LL long long
#define REP(i, x, n) for(int i = x; i < n; ++i)
#define mst(Arr, x) memset(Arr, x, sizeof(Arr))
const int qq = 1e5 + 10;
LL n, m;
bool check(LL x, LL k){
LL sum = (1LL + x) * x / 2;
if(k - sum <= 0) return true;
return false;
}
int main(){
scanf("%lld%lld", &n, &m);
if(n <= m){
printf("%lld\n", n);
return 0;
}
n -= m;
n *= 2LL;
LL d = sqrt(n);
while(d * (d + 1) < n) d++;
printf("%lld\n", d + m);
return 0;
}
J:思维
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <string>
#include <map>
#include <set>
#include <utility>
using namespace std;
typedef long long ll;
typedef pair<int, int> pill;
const int qq = 2e5 + 10;
int n, m, k;
struct Item{
int a, b;
bool operator < (const Item &it)const{
return b - a > it.b - it.a;
}
}item[qq];
int main(){
scanf("%d%d", &n, &k);
int cnt = 0;
for(int i = 0; i < n; ++i)
scanf("%d", &item[i].a);
for(int i = 0; i < n; ++i){
scanf("%d", &item[i].b);
if(item[i].b < item[i].a) cnt++;
}
sort(item, item + n);
ll sum = 0;
for(int i = 0; i < k; ++i)
sum += item[i].a;
int p;
for(p = k; p < n; ++p)
if(item[p].b - item[p].a >= 0) sum += item[p].a;
else break;
for( ; p < n; ++p)
sum += item[p].b;
printf("%lld\n", sum);
return 0;
}
K: BFS + 优先队列
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <string>
#include <map>
#include <set>
#include <utility>
using namespace std;
#define LL long long
#define pb push_back
#define pill pair<int, int>
#define REP(i, x, n) for(int i = x; i < n; ++i)
const int qq = 1e3 + 10;
const LL INF = 1e16;
LL route[43];
LL dist[qq][qq];
char gra[qq][qq];
int tx, ty;
int k, n, m;
LL val;
char op[10];
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
bool check(int x, int y){
if(x < 1 || y < 1 || x > n || y > m)
return false;
return true;
}
struct Node{
int x, y;
LL dis;
bool operator < (const Node &c)const{
return dis > c.dis;
}
}tmp, now;
void bfs(){
priority_queue<Node> Q;
tmp.x = tx, tmp.y = ty;
tmp.dis = 0;
Q.push(tmp);
while(!Q.empty()){
now = Q.top(), Q.pop();
if(now.x == 1 || now.x == n || now.y == 1 || now.y == m){
printf("%lld\n", now.dis);
return;
}
for(int i = 0; i < 4; ++i){
int x = now.x + dx[i];
int y = now.y + dy[i];
if(!check(x, y)) continue;
if(dist[now.x][now.y] + route[gra[x][y] - 'A'] < dist[x][y]){
dist[x][y] = dist[now.x][now.y] + route[gra[x][y] - 'A'];
tmp.dis = dist[x][y];
tmp.x = x, tmp.y = y;
Q.push(tmp);
}
}
}
}
int main(){
int t; scanf("%d", &t);
while(t--){
scanf("%d%d%d", &k, &m, &n);
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
dist[i][j] = INF;
for(int i = 0; i < k; ++i){
scanf("%s%lld", op, &val);
route[op[0] -'A'] = val;
}
for(int i = 1; i <= n; ++i){
scanf("%s", gra[i] + 1);
for(int j = 1; j <= m; ++j)
if(gra[i][j] == 'E'){
tx = i, ty = j;
}
}
dist[tx][ty] = 0;
bfs();
}
return 0;
}
/**********************************************************************
Problem: 1815
User: Yokile
Language: C++
Result: AC
Time:10336 ms
Memory:27060 kb
**********************************************************************/