Примечания к исследованию разработки и анализа алгоритмов 02 | Вызов августовского обновления

алгоритм

Это второй день моего участия в августовском испытании обновлений.Подробности о событии смотрите:​Испытание августовского обновления

Разработка алгоритма и анализ Тема 1:

Выберите 5 букв (a, b, c, d, e) из строки str, чтобы сформировать пароль

Удовлетворить, a - b * b + c * c * c - d * d * d * d + e * e * e * e * e == n

входить:

(1) Целое число n

(2) строка, состоящая из разных заглавных букв, 5≤длина≤12

вывод:

Пароль str, который соответствует правилам, в противном случае решения нет.

Основной код и комментарии:

/* 5层循环暴力破解 */

int flag = 1;

for (int i = 0; i < s.size() && flag; i++) {

int a = s[i] - 'A' + 1;//临时存放字母的序数

int A = a;//1次方

for (int j = 0; j < s.size() && flag; j++) {

if (i == j) continue;

int b = s[j] - 'A' + 1;

int B = b * b;//2次方

for (int k = 0; k < s.size() && flag; k++) {

if (i == k || j == k) continue;

int c = s[k] - 'A' + 1;

int C = c * c * c;//3次方

for (int l = 0; l < s.size() && flag; l++) {

if (i == l || j == l || k == l) continue;

int d = s[l] - 'A' + 1;

int D = d * d * d * d;//4次方

for (int m = 0; m < s.size() && flag; m++) {

if (i == m || j == m || k == m || l == m) continue;

int e = s[m] - 'A' + 1;

int E = e * e * e * e * e;//5次方

 

int sum = A - B + C - D + E;

if (sum == n) {

flag = 0;

cout << (char)(a + 'A' - 1);

cout << (char)(b + 'A' - 1);

cout << (char)(c + 'A' - 1);

cout << (char)(d + 'A' - 1);

cout << (char)(e + 'A' - 1);

cout << endl;

}

}//m

}//l

}//k

}//j

}//i

Результаты теста: /* введите 1 */

int n = 1;

s = "ABCDEFGHIJKL";

/* ввод 2 */

int n = 11700519;

s = "ZAYEXIWOVU";

/* ввод 3 */

int n = 3072997;

s = "SOUGHT";

/* ввод 4 */

int n = 1234567;

s = "THEQUICKFROG";

Выходной результат:

图片1.png

图片2.png

图片3.png

图片4.png

Разработка алгоритма и анализ Тема 2:Максимальная клика: полный подграф с наибольшим количеством вершин в неориентированном графе G.

Полный граф: между любыми двумя вершинами существует ребро.

 

входить:

(1) n вершин, пронумерованных 1...n

(2) m ненаправленных ребер

вывод:

Количество вершин в наибольшей клике

  Входной образец:

5 6 //Первая строка n m: n вершин, m ребер

1 2 //Строка m ниже (s, t): есть ребро между вершиной s и вершиной t

2 3

2 4

3 4

3 5

4 5

Основной код и комментарии:


int max = 1;

for (int i = 1; i <= n; i++) {//依次遍历n个顶点

 

/* 遍历n个点 */

queue * q = new queue();

for (int j = i + 1; j <= n; j++) {

if (G[i][j]) {//若从顶点i到顶点j有边,顶点j入队

q->in(j);

}

}

 

/* 初始cur_max=1,因为[当前顶点]与[最近准备出队顶点]之间,必存在边 */

int cur_max = 1;

while (!q->isEmpty()) {

int val = q->out();//依次出队与当前顶点相邻的顶点

int flag = 1;//==1时,表示还没破坏完全图的规则

for (int j = 0; j < q->getSize(); j++) {//遍历[队列剩余顶点]

if (!G[val][q->get()]) {//如果[当前出队顶点]与[队列中剩余的所有顶点]之间无边,就不能保证完全图,退出当前循环

flag = 0;

break;

}

}

if (flag) cur_max++;//累计当前最大团的顶点个数

}

max = cur_max > max ? cur_max : max;

delete(q);

}

входить: 5 6

1 2

2 3

2 4

3 4

3 5

4 5

вывод: результат правильный

图片5.png