刷题(主要是DFS) 2020年3月12日

1.

Sample Input

    9
    5 2 1 5 2 1 5 2 1
    4
    1 2 3 4
    0

Sample Output

    6
    5
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[100];
bool vis[100];
int ans;
int f;
int n;
int sum;
bool cmp(int a, int b) {
	return a > b;
}

void dfs(int x, int len, int g, int num) {
	//当前下标	当前长度 目标长度		已匹配数量
	//cout << "1x= " << x << " len = " << len << " g=" << g << " num=" << num << endl;
 	if(f)	return;
	if(num == n) {
		f = 1;
		return;
	}
	for(int i = x; i < n; ++i) {
		if(!vis[i] && a[i] + len <= g) {
			vis[i] = 1;
			if(a[i] + len == g) {
				//cout << "2x= " << x << " len = " << len << " g=" << g << " num=" << num << endl;
				dfs(0, 0, g, num + 1);
			}
			else {
				//cout << "3x= " << x << " len = " << len << " g=" << g << " num=" << num << endl;
				dfs(i + 1, a[i] + len, g, num + 1);
			}
			//cout << 666 << endl;
			vis[i] = 0;	//去除标记
			if(f)	return;
			if(len == 0)	return;	//剪枝
			while(i < n && a[i+1] == a[i]) ++i;	//剪枝
		}
	}
}


int main () {
	while(cin >> n) {
		//memset(vis, 0, sizeof vis);
		if(!n) {
			break;
		}
		sum = 0;
		memset(a, 0, sizeof a);
		for(int i = 0; i < n; ++i) {
			cin >> a[i];
			sum += a[i];
		}
		
		sort(a, a + n, cmp);
		for(int i = a[0]; i <= sum; ++i) {
			if(i == sum) {
				cout << sum << endl;
			}
			else if(sum % i == 0) {//剪枝
				f = 0;
				dfs(0, 0, i, 0);
				if(f == 1) {
					cout << i << endl;
					break;
				}
			}
		}
	}

}

 2.

Sample Input

    1
    8
    5
    0

Sample Output

    1
    92
    10
#include<iostream>
#include<cstring>
#include<cmath>

using namespace std;
int vis[3][50], P[15];//三个方向 ↖↑↗在此三个方向都不能有皇后 
int n, sum;

void  DFS(int row){
	int i;
	if (row == n + 1){//已经够n行了
		sum++;
		return;
	}
	for (i = 1; i <= n; i++){ // i表示第i列遍历 row表示第row行
		//	关注对角线上数的行标和列标的特征
		if (vis[0][row - i + n] == 0 && vis[1][i] == 0 && vis[2][row + i] == 0){//回溯
			vis[0][row - i + n] = vis[1][i] = vis[2][row + i] = 1;//变值
			DFS(row + 1);//深搜
			vis[0][row - i + n] = vis[1][i] = vis[2][row + i] = 0;//回溯
		}
	}
}

int main()
{
	for (n = 1; n <= 10; n++){//先打表不然会超时的
		memset(vis, 0, sizeof(vis));
		sum = 0;
		DFS(1);
		P[n] = sum;
	}
	while (cin >> n, n){
		cout << P[n] << endl;
	}
	return 0;
}

 3

Sample Input

    7 1 2 ? 6 ? 3 5 8
    ? 6 5 2 ? 7 1 ? 4
    ? ? 8 5 1 3 6 7 2
    9 2 4 ? 5 6 ? 3 7
    5 ? 6 ? ? ? 2 4 1
    1 ? 3 7 2 ? 9 ? 5
    ? ? 1 9 7 5 4 8 6
    6 ? 7 8 3 ? 5 1 9
    8 5 9 ? 4 ? ? 2 3

Sample Output

    7 1 2 4 6 9 3 5 8
    3 6 5 2 8 7 1 9 4
    4 9 8 5 1 3 6 7 2
    9 2 4 1 5 6 8 3 7
    5 7 6 3 9 8 2 4 1
    1 8 3 7 2 4 9 6 5
    2 3 1 9 7 5 4 8 6
    6 4 7 8 3 2 5 1 9
    8 5 9 6 4 1 7 2 3


#include <bits/stdc++.h>
using namespace std;
char temp;
int ma[11][11] = {0};
int num = 0;
struct dian
{
	int x, y;
}a[100];

bool isOK(int k, int step) {
	int x, y;
	for(int i = 0; i < 9; ++i) {
		if(ma[a[step].x][i] == k || ma[i][a[step].y] == k){
			return 0;
		}
	}
		//剪枝
		//判断这个数所处的那个小九宫格里面有没有重复的数
	x = (a[step].x) / 3 * 3;
	y = (a[step].y) / 3 * 3;
	//这步十分重要
	for(int i = x; i < x + 3; ++i) {
		for(int j = y; j < y + 3; ++j) {
			if(ma[i][j] == k) {
				return 0;
			}
		}
	} 
	return 1;
}

void Ptu(int m[][11]) {
	for(int i = 0; i < 9; ++i) {
		for(int j = 0; j < 9; ++j) {
			cout << m[i][j];
			if(j != 8) {
				cout << " ";
			}
		}
		cout << endl;
	}
}

void DFS(int step) {
	//cout << step << endl;
	if(step == num) {
		// for(int i=0; i < 9; i++){ 
  //          for(int j=0; j < 8; j++) {
  //           cout << ma[i][j] << " ";
  //          }
  //          cout << ma[i][8] << endl;//直接在这里输出结果,要不然会发生可怕的事~
  //       }
		Ptu(ma);
		return;	//需要在这里输出结果,否则会被还原
	}
	for(int i = 1; i <= 9; ++i) {
		if(isOK(i, step)) {
			ma[a[step].x][a[step].y] = i;
			DFS(step + 1);
			ma[a[step].x][a[step].y] = 0;
		}
	}
	return;
}
int main () {
	int t = 0;
	while(cin >> temp){
		num = 0;
		if(temp == '?') {
			a[num].x = 0;
			a[num].y = 0;
			num++;
			ma[0][0] = 0;
 		}
		else {
			ma[0][0] = temp - '0'; 
		}
		//memset(a, 0, sizeof a);
		for(int i = 0; i < 9; ++i) {
			for(int j = 0; j < 9; ++j) {
				if(i == 0 && j == 0) {
					continue;
				}
				cin >> temp;
				if(temp == '?') {
					
					//ma[i][j] == 0;
					a[num].x = i;
					a[num].y = j;
					num++;
					ma[i][j] = 0;
 				}
				else {
					ma[i][j] = temp - '0'; 
				}
			}
		}
		if(t++) {
			putchar(10);
		}
		DFS(0);
	}
	return 0;
}

 4.

#include <bits/stdc++.h>
using namespace std;
int i = 0;
string sh;
int f() {
	int mx = 0;
	int temp = 0;
	int len = sh.length();
	while(i < len) {
		char t = sh[i++];
		if(t == '(') {
			temp += f();
		}
		else if (t == ')') {
			break;
		}
		else if(t == '|') {
			mx = max(temp, mx);
			temp = 0;
		}
		else {
			temp++;
		}
	}
	return max(mx, temp);
}
	
int main () {
	cin >> sh;
	cout << f() << endl;
}

 5.

//这道题最后一组样例被T了 只得了75分
//拿到满分需要用树的直径优化,改日再写
//注意要标记初始点
#include <bits/stdc++.h> using namespace std; int lu[10000][10000]; bool vis[100000]; int sum = 0; int temp = 0; int n; void DFS(int x) { //cout << "dfs"<<x<<endl; //cout << "x:" << x << endl; // if(x == n + 1) { // //cout << 66 << endl; // sum = max(temp, sum); // temp = 0; // return; // } for(int i = 1; i <= n; ++i) { vis[x] = 1; int tt = x < i ? lu[x][i] : lu[i][x]; if(tt && !vis[i]){ vis[i] = 1; // cout << "temp:" << temp << endl; // cout << "tt:" << tt << endl; temp += tt; DFS(i); vis[i] = 0; sum = max(temp, sum); temp -= tt; } vis[x] = 0; } //cout << "fdfs"<<x<<endl; } int main () { cin >> n; for(int i = 0; i < n - 1; ++i) { int a,b,c; cin >> a >> b >> c; if(a > b) swap(a, b); lu[a][b] = max(lu[a][b], c); } for(int i = 1; i <= n; ++i) { //memset(vis, 0, sizeof vis); DFS(i); } int s = 0; for(int i = 1; i <= sum; i++) { s += (i + 10); } //cout << sum << endl; cout << s << endl; }
作者:LightAc
出处:https://www.cnblogs.com/lightac/
联系:
Email: dzz@stu.ouc.edu.cn
QQ: 1171613053
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/lightac/p/12483526.html