1、逆时针遍历+报数
M*N的矩阵,从(0,0)开始,先从顺时针从最外围走到原点,再从里面一层继续顺时针兜圈,直至走完
//
// ->->->->->->
// | |
// ^ v
// | |
// <-<-<-<-<-<-v
//
每个元素从1开始编号,若编号的个位数为7,十位数为奇数,则被挑选出来,按顺序输出挑选的编号列表
代码:
#include<iostream>
using namespace std;
int main()
{
int M, N;
cin >> M >> N;
int count = 1;
int i = 0, j = 0, cycle = 0;
while (count < M*N)
{
for (; j < N - cycle - 1; j++)
{
if (count % 10 == 7 && count/10%2 == 1)
{
cout << i << "," << j << endl;
}
count++;
}
for (; i < M - cycle - 1; i++)
{
if (count % 10 == 7 && count/10%2 == 1)
{
cout << i << "," << j << endl;
}
count++;
}
for (; j > cycle; j--)
{
if (count % 10 == 7 && count/10% 2 == 1)
{
cout << i << "," << j << endl;
}
count++;
}
for (; i > cycle+1; i--)
{
if (count % 10 == 7 && count/10 % 2 == 1)
{
cout << i << "," << j << endl;
}
count++;
}
cycle++;
}
return 0;
}
2、合法的二叉树
//2021/8/19华为笔试
//
//给出二叉树每个节点深度,计算符合条件的二叉树有多少种
//
//输入:
//第一行,一个整数N。表示有多少个节点,(1<=N<=1000)
//第二行,N个整数,d1,d2,…,dn。表示每个节点的深度,(0<=di<=N-1)。
//
//输出:
//满足条件的二叉树个数,数目可能很大,需要mod(10^9+7)。
//
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int MOD = pow(10, 9) + 7;
int Comb(int n, int k)
{
if (k == 0 || k == n)
return 1;
k = min(k, n - k);
long long top = 1;
for (int i = n; i > n - k; i--)
{
top *= i;
}
long long down = 1;
for (int i = 1; i <= k; i++)
{
down *= i;
}
return (top / down) % MOD;
}
int main()
{
int N;
while (cin >> N)
{
vector<int> d(1001); //存储每个度的数目
int count = 0; //记录最大深度
for (int i = 0; i < N; i++)
{
int tmp_d;
cin >> tmp_d;
count = max(count, tmp_d);
d[tmp_d]++;
}
if (d[0] != 1)
return 0;
vector<int > dp(1001);
dp[0] = 1;
for (int i = 1; i <= count; i++)
{
int max_num = pow(2, i); //该层理论最多产生的节点数
if (d[i] > max_num)
return 0;
int act_num = 2 * d[i - 1]; //该层实际最多产生的节点数
if (d[i] > act_num)
return 0;
//Comb为计算组合,即act_num中挑出d[i]个来,有多少组合
dp[i] = dp[i - 1] * Comb(act_num, d[i]);
dp[i] %= MOD;
}
cout << dp[count] << endl;
}
return 0;
}
3、俄罗斯方块
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
int helper(vector<int>& frame, vector<int>& brick)
{
int frame_n = frame.size(), brick_n = brick.size();
int res = 1000000;
for (int i = 0; i < frame_n - brick_n + 1; i++)
{
int max_h = 0, total_max_h;
for (int j = 0; j < brick_n; j++)
max_h = max(max_h, brick[j] + frame[i + j]); //重合部分最大高度
total_max_h = max_h;
int r = 100000;
for (int j = 0; j < frame_n; j++)
{
total_max_h = max(total_max_h, frame[j]); //当前组合的最大高度
if (j < i) //r能消除的高度
r = min(r, frame[j]);
else if (j >= (i + brick_n))
r = min(r, frame[j]);
else
{
int tmp1 = frame[j], tmp2 = brick[j - i];
if (tmp1 + tmp2 == max_h) //关键点,用于处理下落块被杠在了空中,max_h地方即为frame与brick联通的地方,因此和max_h(frame+brick)比较
r = min(r, max_h);
else //其他地方,有可能是悬空的,因此只能和frame比较
r = min(r, tmp1);
}
}
res = min(res, total_max_h - r);
}
return res;
}
int main()
{
string s1, s2;
cin >> s1 >> s2;
vector<int> frame(s1.size()), brick(s2.size());
for (int i = 0; i < s1.size(); i++)
frame[i] = s1[i] - '0';
for (int i = 0; i < s2.size(); i++)
brick[i] = s2[i] - '0';
cout << helper(frame, brick);
return 0;
}