A.水题
B.模拟
有一张网格纸, 每次可以向右或向上翻折, 翻完之后,在某些地方打孔, 问有多少个孔?(其实就是有多少层纸)。
思路:
1.用一个二维数组,在纸面内的初始化为1.
2.每次翻折先把0-c/2移到最左边或最下面,再进行翻折(这样数组不用开很大)
3.最后直接输出答案
C.模拟
每一层楼的租金是这层楼的层数,现在有b的租金,问能租下的最长连续楼层(输出最低楼和层数),而且必须恰好用完。
思路:
1.等差数列,假设从第k层,一直到k+t层。那么b=(t+1)k+(t+1)*t/2,即k=(2*b-t(t+1))/((t+1)*2);
2.枚举t(sqrt(n)级别),保证k为整数,更新最大值即可
D.搜索
用mp[a][b]=1表示a赢b,反之mp[a][b] = 0.用win[i]表示第i支球队赢的场数。
思路:
1.要保证每只球队输赢相等,显然就是(n-1)/2
2.直接暴力搜索就行。
3.过程中大于(n-1)/2就剪枝。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n, m;
int win[10];
int ta[10][10];
int ans = 0;
void dfs(int a, int b){
if(a == n && b == n){
ans++;
return;
}
if(b == n+1){
a++;
b = 0;
}
if(a == b || ta[a][b] != -1)
dfs(a, b+1);
else{
if(win[a] < (n-1)/2){
ta[a][b] = 1;
ta[b][a] = 0;
win[a]++;
dfs(a, b+1);
win[a]--;
ta[a][b] = -1;
ta[b][a] = -1;
}
if(win[b] < (n-1)/2){
ta[a][b] = 0;
ta[b][a] = 1;
win[b]++;
dfs(a, b+1);
win[b]--;
ta[a][b] = -1;
ta[b][a] = -1;
}
}
}
int main(){
while(scanf("%d", &n) == 1){
if(n == 0)
break;
ans = 0;
scanf("%d", &m);
for(int i = 1; i <= n; i++){
win[i] = 0;
for(int j = 1; j <= n; j++){
ta[i][j] = -1;
}
}
int a, b;
for(int i = 1; i <= m; i++){
scanf("%d %d", &a, &b);
win[a]++;
ta[a][b] = 1;
ta[b][a] = 0;
}
int flag = 1;
for(int i = 1; i <= n; i++){
if(win[i] > (n-1)/2){
printf("0\n");
flag = 0;
break;
}
}
if(flag == 0)
continue;
dfs(1, 1);
printf("%d\n", ans);
}
return 0;
}
K.模拟
引号内只允许错一个,引号外不能错
思路:
1.直接模拟就行