前面两道题暴力搜索
第三题 蛇形填数
思路
第一行第一列 1+4*0
第二行第二列 1+4*1
第三行第三列 1+4*1+4*2
...
第n行第n列 1+4*1+4*2+...+4*(n-1)
代码
int main(){
int sum=1;
for(int i=0; i<20; i++){
sum += 4*i;
}
cout<< sum << endl;
return 0;
}
第四题:7段码
题目描述
小蓝要用七段码数码管来表示一种特殊的文字。 七段码上图给出了七段码数码管的一个图示,数码管中一共有 7 段可以发光的二极管,分别标记为 a,
b, c, d, e, f,
g。小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符的表达时,要求所有发光的二极管是连成一片的。 例如:b
发光,其他二极管不发光可以用来表达一种字符。 例如:c
发光,其他二极管不发光可以用来表达一种字符。这种方案与上一行的方案可以用来表示不同的字符,尽管看上去比较相似。 例如:a, b, c, d,
e 发光,f, g 不发光可以用来表达一种字符。 例如:b, f
发光,其他二极管不发光则不能用来表达一种字符,因为发光的二极管没有连成一片。 请问,小蓝可以用七段码数码管表达多少种不同的字符?
思路
并查集连通,dfs枚举所有可能,再判断连通块个数,为一则答案加一
代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 10;
int e[N][N];
int father[N];
int used[N];
int ans;//总数
void init(){//为一表示相连
//a b c d e f g
//1 2 3 4 5 6 7
e[1][2]=e[1][6]=1;
e[2][1]=e[2][7]=e[2][3]=1;
e[3][2]=e[3][4]=e[3][7]=1;
e[4][3]=e[4][5]=1;
e[5][4]=e[5][6]=e[5][7]=1;
e[6][1]=e[6][5]=e[6][7]=1;
}
int find(int x){//并查集找根结点
if(father[x] != x){
father[x] = find(father[x]);
}
return father[x];
}
void dfs(int u){
if(u>7){
for(int i=1;i<=7;i++)father[i]=i;//初始化 并查集
for(int i=1; i<=7; i++){
for(int j=1; j<=7; j++){
if(used[i]&&used[j]&&e[i][j]){
int fx = find(i),fy = find(j);
if(fx!=fy) father[fx] = fy;//加入连通块
}
}
}
int num=0;//连通块数
for(int i=1;i<=7;i++){
if(used[i] && father[i]==i) num++;
}
if(num==1) ans++;
return;
}
used[u]=1;
dfs(u+1);
used[u]=0;
dfs(u+1);
}
int main(){
init();
dfs(1);
cout << ans << endl;
return 0;
}
第五题:平面分割
题目描述
20 个圆和20 条直线最多能把平面分成多少个部分?
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int cal(int n){
int ans=2;//第一个圆平面分成2部分
for(int i=2; i<=n; i++){//再画19个圆
ans += (i-1)*2;
}
ans += n*2;//第一条直线和20个圆相交,有20*2个相交点,平面增加40部分
for(int i=2; i<=n; i++){//再画19条线
ans += 2*n+i;第i条直线和前面20个圆和i-1条线最多产生40+i-1个焦点,被分成40+i段,亦即增加40+i个部分
}
return ans;
}
int main(){
cout << cal(20) << endl;
return 0;
}