目录
- 7-1 最大公约数
- 7-2 百钱百鸡
- 7-3 国王的奖励(暴力版)
- 7-4 powmod(暴力版)
- 7-5 平面最近点对(暴力版)
- 7-6 国王的奖励(分治版)
- 7-7 powmod(分治版)
- 7-8 平面最近点对(分治版)
- 7-9 最大子段和(分治版)
- 7-10 起泡排序
- 7-11 棋盘覆盖问题
- 7-12 逆序对
- 7-13 铺设油井管道
- 7-14 铺设油井管道plus
- 7-15 最大子段和(动态规划版)
- 7-16 最大子段和(数据加强)
- 7-17 数塔
- 7-18 最短路径
- 7-19 排序问题
- 7-20 旅行商问题
- 7-21 最短路径算法(Floyd-Warshall)
- 7-22 最长有序子序列
- 7-23 最长公共子序列长度
- 7-24 0-1背包
- 7-25 最优二叉搜索树
- 7-26 选课(贪心)
- 7-27 汉密尔顿回路
- 7-28 八皇后问题(*)
- 7-29 任务分配
- 7-30 吉林跑男
7-1 最大公约数
#include<iostream>
#include<cstdio>
using namespace std;
long fun(long m, long n) {
long y;
while (n > 0) {
y = m % n;
m = n;
n = y;
}
return m;
}
int main() {
long n, m;
cin >> m >> n;
cout << fun(m, n);
return 0;
}
7-2 百钱百鸡
#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>
#include<stdio.h>
int main() {
for (int i = 0; i <= 20; i++) {
for (int j = 0; j <= 33; j++) {
for (int k = 0; k <= 99;k+=3) {
if ((i + j + k == 100 )&& (5 * i + 3 * j + k / 3 == 100)) {
printf("cock=%d,hen=%d,chicken=%d\n", i, j, k);
}
}
}
}
return 0;
}
7-3 国王的奖励(暴力版)
#include<iostream>
#include<cstdio>
using namespace std;
#include <stdio.h>
#include<math.h>
#include<cmath>
const int mod = 100000007;
int main() {
int t = 0;
cin >> t;
for (int i = 0; i < t; i++) {
int q, n;
cin >> q >> n;
long ans = 1;
long jia = 1;
while (--n>0) {
jia *= q;
jia %= mod;
ans += jia;
ans %= mod;
}
cout << ans << endl;
}
return 0;
}
7-4 powmod(暴力版)
#include<iostream>
#include<cstdio>
using namespace std;
#include <stdio.h>
#include<math.h>
#include<cmath>
int qumo(int a, int b, int m)
{
if (b == 0) return 1;
int x = qumo(a, b / 2, m);
int ans = (int)x * x % m;
if (b % 2 == 1) ans = ans * a % m;
return (int)ans;
}
int main() {
int a, b, m;
cin >> a >> b >> m;
cout<<qumo(a, b, m);
}
7-5 平面最近点对(暴力版)
#include<iostream>
#include<cstdio>
using namespace std;
#include <stdio.h>
#include<math.h>
#include<cmath>
int main(){
int n = 0;
cin >> n;
int a[100000][2];
for (int i = 0; i < n; i++) {
int x;
int y;
cin >> x >> y;
a[i][0] = x;
a[i][1] = y;
}
long ans = 10000000000;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int x1 = a[i][0];
int y1 = a[i][1];
int x2 = a[j][0];
int y2 = a[j][1];
long now = pow(x1 - x2, 2) + pow(y1 - y2, 2);
if (ans > now) {
ans = now;
}
}
}
double ansD = sqrt(ans);
printf("%.4f", ansD);
return 0;
}
7-6 国王的奖励(分治版)
#include<stdio.h>
#include<iostream>
using namespace std;
#define mod 100000007
long long qmul(long long a,long long b){
a = (a % mod + mod) % mod;
b = (b % mod + mod) % mod;
long long c = a * (long double)b / mod;
long long ans = a * b - c * mod;
if(a < 0){
a += mod;
}else if(a >= mod){
a -= mod;
}
return ans;
}
long long qpow(long long base,long long power){
base %= mod;
long long ans = 1;
while(power){
if(power & 1){
ans = qmul(ans,base);
}
base = qmul(base,base);
power >>= 1;
}
return ans;
}
long long sum(long long q,long long n){
if(n == 1){
return 1;
}
if(n & 1){
return (qmul(1 + qpow(q,n >> 1), sum(q, n >> 1)) + qpow(q,n-1)) % mod;
}
else{
return qmul(1 + qpow(q,n >> 1), sum(q, n >> 1));
}
}
int main(){
int m;
cin >> m;
long long q,n;
while(m--){
cin >> q >> n;
if(q == 1){
cout <<n % mod << endl;
}else{
cout << sum(q, n) << endl;
}
}
return 0;
}
7-7 powmod(分治版)
#include<iostream>
#include<math.h>
using namespace std;
int main(void){
long long a, n, m;
cin >> a >> n >> m;
a %= m;
long long ans = 1;
while (n) {
if (n & 1) {
ans = (ans * a) % m;
}
a = (a * a) % m;
n >>= 1;
}
cout << ans;
return 0;
}
7-8 平面最近点对(分治版)
#include<iostream>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;
const int m = 200003;
class node{
public:
double x;
double y;
node(){
}
node(double x, double y){
this -> x = x;
this -> y = y;
}
};
node s[m];
node p[m];
int cmp(node a, node b){
return a.y < b.y;
}
double distance(node a,node b){
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y-b.y));
}
double close(node s[],int l,int r){
double d1, d2, d3, d;
if(r-l == 1){
return distance(s[l],s[r]);
}
if(r - l == 2){
d1 = distance(s[l], s[r]);
d2 = distance(s[l], s[l+1]);
d3 = distance(s[r-1], s[r]);
if(d1<d2)d=d1;
else d=d2;
if(d3<d)d=d3;
return d;
}
int index=0;
int mid=l+(r-l)/2;
d1=close(s,l,mid);
d2=close(s,mid+1,r);
if(d1<d2)d=d1;
else d=d2;
for(int i=mid;i>=l&&s[mid].y-s[i].y<d;i--){
p[index++]=s[i];
}
for(int j=mid+1;j<=r&&s[j].y-s[mid].y<d;j++){
p[index++]=s[j];
}
sort(p,p+index,cmp);
for(int i=0;i<index;i++){
for(int j=i+1;j<index;j++){
if(p[j].y-p[i].y>d){
break;
}
d3=distance(p[j],p[i]);
if(d3<d)d=d3;
}
}
return d;
}
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>s[i].x>>s[i].y;
}
sort(s,s+n,cmp);
double ans=close(s,0,n-1);
printf("%.4f",ans);
}
7-9 最大子段和(分治版)
#include<iostream>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;
const int m = 210003;
int s[m];
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> s[i];
}
bool flag = true;
for (int i = 0; i < n; i++) {
if (s[i] >= 0)flag = false;
}
if (flag) {
cout << 0;
return 0;
}
int pre = s[0];
int ans = s[0];
for (int i = 1; i < n; i++) {
if (pre + s[i] > s[i]) {
pre += s[i];
}
else {
pre = s[i];
}
if (ans < pre)ans = pre;
}
cout << ans;
return 0;
}
7-10 起泡排序
#include<iostream>
long long ans = 0;
#define int long long
#define N 200001
using namespace std;
int a[N], b[N];
void Merge(int left, int mid, int right)
{
int i = left, j = mid + 1, k = left;
while (i <= mid && j <= right)
{
if (a[i] <= a[j])
{
b[k++] = a[i++];//将a[i],a[j]中较小者放入b[k]
}
else
{
b[k++] = a[j++];
ans += mid - i + 1;
}
}
while (i <= mid)
b[k++] = a[i++];
while (j <= right)
b[k++] = a[j++];
for (long long i = left; i <= right; i++)
a[i] = b[i];//将有序序列换回来
}
void MergeSort(int left, int right)
{
int mid;
if (left >= right)
return;
else
{
mid = (left + right) / 2;
MergeSort(left, mid);
MergeSort(mid + 1, right);
Merge(left, mid, right);
}
}
signed main()
{
int n;
cin >> n;
for (long long i = 0; i < n; i++)
cin >> a[i];
MergeSort(0, n - 1);
cout << ans;
}
7-11 棋盘覆盖问题
#include<iostream>
#include<iomanip>
#include<cstdio>
#include <stdio.h>
#include<math.h>
#include<cmath>
using namespace std;
int boardSize;
int count = 1;
int board[100][100];
void chessboard(int tr, int tc, int dr, int dc, int size)
{
if (size == 1)//递归结束
{
return;
}
int t = count++;
int s = size / 2;
if (dr < tr + s && dc < tc + s)//如果在左上角部分
{
chessboard(tr, tc, dr, dc, s);
}
else
{
board[tr + s - 1][tc + s - 1] = t;
chessboard(tr, tc, tr + s - 1, tc + s - 1, s);
}
if (dr < tr + s && dc >= tc + s)
{
chessboard(tr, tc + s, dr, dc, s);
}
else
{
board[tr + s - 1][tc + s] = t;
chessboard(tr, tc + s, tr + s - 1, tc + s, s);
}
if (dr >= tr + s && dc < tc + s)//如果在右上角
{
chessboard(tr + s, tc, dr, dc, s);
}
else
{
board[tr + s][tc + s - 1] = t;
chessboard(tr + s, tc, tr + s, tc + s - 1, s);
}
if (dr >= tr + s && dc >= tc + s)//如果在右下角部分
{
chessboard(tr + s, tc + s, dr, dc, s);
}
else
{
board[tr + s][tc + s] = t;
chessboard(tr + s, tc + s, tr + s, tc + s, s);
}
}
int main() {
cout.flags (ios::left);
cin>>boardSize;
int dr,dc;
cin>>dr>>dc;
chessboard(0, 0, dr, dc, boardSize);
for (int i = 0; i < boardSize; i++)
{
for (int j = 0; j < boardSize; j++)
{
cout <<setw(5)<< board[i][j];
}
cout << endl;
}
return 0;
}
7-12 逆序对
#include<iostream>
using namespace std;
const int n=1000009;
int a[n];
int b[n];
long long ans=0;
void merge(int l,int m,int r){
int i,j,p;
i=l;
j=m;
p=l;
while(i<m&&j<=r){
if(a[i]<=a[j]){
b[p++]=a[i++];
}else{
ans+=m-i;
b[p++]=a[j++];
}
}
while(i<m){
b[p++]=a[i++];
}
while(j<=r){
b[p++]=a[j++];
}
i=l;
p=l;
while(p<=r){
a[i++]=b[p++];
}
}
void merge_sort(int l,int r){
if(l<r){
int m=(l+r)/2;
merge_sort(l,m);
merge_sort(m+1,r);
merge(l,m+1,r);
}
}
int main(){
int m;
cin>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
merge_sort(1,m);
cout<<ans;
}
7-13 铺设油井管道
#include <stdio.h>
#include <stdlib.h>
#include<math.h>
int n;
int a[1001010];
int k;
int mid;
void fid(int left,int right)
{
int temp=a[left];
int i=left;
int j=right;
if(i>j)
return;
while(i<j)
{
while(i<j&&a[j]>temp)
j--;
a[i]=a[j];
while(i<j&&a[i]<=temp)
i++;
a[j]=a[i];
}
a[i]=temp;
if(i==k)
mid=a[i];
else if(i>k)
fid(left,i-1);
else
fid(i+1,right);
return ;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int x;
scanf("%d%d",&x,&a[i]);
}
if(n%2==0)
k=n/2;
else
k=n/2+1;
fid(1,n);
long long sum=0;
for(int i=1;i<=n;i++)
sum+=abs(a[i]-mid);
printf("%lld",sum);
return 0;
}
7-14 铺设油井管道plus
#include <stdio.h>
#include <stdlib.h>
#include<math.h>
int n;
int a[2001000];
int k;
int mid;
void fid(int left,int right)
{
int temp=a[left];
int i=left;
int j=right;
if(i>j)
return;
while(i<j)
{
while(i<j&&a[j]>temp)
j--;
a[i]=a[j];
while(i<j&&a[i]<=temp)
i++;
a[j]=a[i];
}
a[i]=temp;
if(i==k)
mid=a[i];
else if(i>k)
fid(left,i-1);
else
fid(i+1,right);
return ;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int x;
scanf("%d%d",&x,&a[i]);
}
if(n%2==0)
k=n/2;
else
k=n/2+1;
fid(1,n);
long long sum=0;
for(int i=1;i<=n;i++)
sum+=abs(a[i]-mid);
printf("%lld",sum);
return 0;
}
7-15 最大子段和(动态规划版)
#include<stdio.h>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
const int n = 1000000;
int a[n];
int main() {
int n;
scanf("%d", &n);
int f;
scanf("%d", &f);
int p = f;
int ans = f;
bool flag = true;
for (int i = 1; i < n; i++) {
int t;
scanf("%d", &t);
if (flag && t > 0)flag = false;
if (p + t > t) {
p += t;
}
else {
p = t;
}
if (p > ans)ans = p;
}
if (flag) {
printf("0\n");
return 0;
}
printf("%d\n", ans);
return 0;
}
7-16 最大子段和(数据加强)
#include<iostream>
#include<stdio.h>
using namespace std;
struct gen
{
int seed, mul, bias, mod;
int get()
{
seed = (seed * mul + bias) % mod;
return seed - (mod / 2);
}
};
int n;
int a[100000001];
int main()
{
cin >> n;
gen g;
cin >> g.seed >> g.mul >> g.bias >> g.mod;
int sum=0;
int ans=0;
for (int i = 1; i <= n; i++)
{
a[i] = g.get();
if(sum+a[i]>a[i]){
sum+=a[i];
}else{
sum=a[i];
}
if(sum<0)sum=0;
if(ans<sum)ans=sum;
}
// a数组即为题目给出的数组
printf("%d\n",ans);
return 0;
}
7-17 数塔
#include <iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 103;
int a[N][N];
int DataTower(int d[N][N],int n) {
int maxAdd[N][N] = { 0 };
int i, j;
for (j = 0; j < n; j++) {
maxAdd[n - 1][j] = d[n - 1][j];
}
for (i = n - 2; i >= 0; i--) {
for (j = 0; j <= i; j++) {
if (maxAdd[i + 1][j] > maxAdd[i + 1][j + 1]) {
maxAdd[i][j] = d[i][j] + maxAdd[i + 1][j];
}
else {
maxAdd[i][j] = d[i][j] + maxAdd[i + 1][j + 1];
}
}
}
/*
printf("路径为:%d", d[0][0]);
j = path[0][0];
for (i = 1; i < n; i++) {
printf("-->%d", d[i][j]);
j = path[i][j];
}
*/
return maxAdd[0][0];
}
int main() {
int c;
cin >> c;
while (c-- > 0) {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
cin >> a[i][j];
}
}
int ans = DataTower(a, n);
cout << ans << endl;
}
return 0;
}
7-18 最短路径
#include <iostream>
#include<algorithm>
#include<cmath>
using namespace std;
//2147483647
const int m = 100000000;
const int N = 1003;
int arc[N][N];
int vnum = 0;
int CreatGraph() {
int i, j, k;
int weight;
int arcnum;//顶点,边
cin >> vnum >> arcnum;
for (i = 0; i < vnum; i++) {
for (j = 0; j < vnum; j++) {
arc[i][j] = m;
}
}
for (k = 0; k < arcnum; k++) {
cin >> i >> j >> weight;
arc[--i][--j] = weight;
}
return vnum;
}
int BackPath(int n) {
int i, j, temp;
int cost[N];
for (i = 1; i < n; i++) {
cost[i] = m;
}
cost[0] = 0;
for (j = 1; j < n; j++) {
for (i = j - 1; i >= 0; i--) {
if (arc[i][j] + cost[i] < cost[j]) {
cost[j] = arc[i][j] + cost[i];
}
}
}
return cost[n - 1];
}
int main() {
CreatGraph();
cout<< BackPath(vnum);
return 0;
}
第二种解法
#include<iostream>
#include<iomanip>
using namespace std;
const int M = 0x3f3f3f;
const int m = 1003;
int a[m][m];
int main() {
int n;
cin >> n;
int b;
cin >> b;
for (int i = 0; i < b; i++) {
int r, c, v;
cin >> r >> c >> v;
a[c-1][r-1] = v;
}
for (int i = 1; i < n; i++) {
int nm = M;
for (int j = 0; j < n; j++) {
if (a[i][j] != 0 && a[i][j] + a[j][0] < nm) {
nm = a[i][j] + a[j][0];
}
}
a[i][0] = nm;
}
cout << a[n - 1][0] ;
return 0;
}
7-19 排序问题
#include<iostream>
#include<stdio.h>
using namespace std;
const int m=105;
int a[m];
void shift(int a[],int k,int n){
int i,j,t;
i=k;
j=2*i+1;
while(j<n){
if(j<n-1&&a[j]<a[j+1])j++;
if(a[i]>a[j])break;
else{
t=a[i];
a[i]=a[j];
a[j]=t;
i=j;
j=2*i+1;
}
}
}
void heapSort(int a[],int n){
int t;
for(int i=(n-1)/2;i>=0;i--){
shift(a,i,n);
}
for(int i=1;i<n;i++){
t=a[0];
a[0]=a[n-i];
a[n-i]=t;
shift(a,0,n-i);
}
}
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
heapSort(a,n);
for(int i=0;i<n;i++){
printf("%d ",a[i]);
}
}
7-20 旅行商问题
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
class Tsp {
private:
int n;
int** d;
int** p;
public:
Tsp(int num);
void s();
};
Tsp::Tsp(int num) {
n = num;
d = new int* [n];
for (int i = 0; i < n; i++) {
d[i] = new int[n];
for (int j = 0; j < n; j++) {
scanf("%d", &d[i][j]);
}
}
/*
* cout << "输入的矩阵为:" << endl;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cout << d[i][j] << " ";
}
cout << endl;
}
cout << endl;
*/
p = new int* [n];
for (int i = 0; i < n; i++) {
p[i] = new int[1 << (n - 1)];
}
}
void Tsp::s() {
for (int i = 0; i < n; i++) {
p[i][0] = d[i][0];
}
for (int i = 1; i < 1 << (n - 1); i++) {
for (int j = 0; j < n; j++) {
p[j][i] = 0x3f3f3f3f;
if ((i>>(j-1) & 1) == 1)continue;
for (int k = 1; k < n; k++) {
if ((i>> (k - 1) & 1) == 0)continue;
if (p[j][i] > d[j][k] + p[k][i ^ (1 << (k - 1))]) {
p[j][i] = d[j][k] + p[k][i ^ (1 << (k - 1))];
}
}
}
}
printf("%d\n", p[0][(1 << (n - 1))-1]);
}
int main() {
int n;
scanf("%d", &n);
int no;
cin >> no;
Tsp t = Tsp(n);
t.s();
return 0;
}
7-21 最短路径算法(Floyd-Warshall)
#include<iostream>
#define INF 9999999
using namespace std;
const int N = 53;
void display(int dist[N][N], int n)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
if (dist[i][j] >= INF) {
cout << -1 << " ";
}
else {
cout << dist[i][j] << " ";
}
cout << endl;
}
}
void Floyd(int arc[N][N], int dist[N][N],int n)
{
int i, j, k;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
dist[i][j] = arc[i][j];
}
}
for (k = 0; k < n; k++)
{
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if (dist[i][k] + dist[k][j] < dist[i][j])
{
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}
}
int main(void)
{
int static arc[N][N];
int static dist[N][N] ;
int n;
cin >> n;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> arc[i][j];
if (i != j && arc[i][j]==0) {
arc[i][j] = INF;
}
}
}
Floyd(arc, dist,n);
display(dist,n);
return 0;
}
7-22 最长有序子序列
#include<iostream>
using namespace std;
const int m=1001;
int a[m];
int l[m];
int n;
int f(){
for(int i=0;i<n;i++){
int max=1;
for(int j=i-1;j>=0;j--){
if(a[j]<a[i]&&l[j]+1>max){
max=l[j]+1;
l[i]=max;
}
}
}
int index=0;
for(int i=1;i<n;i++){
if(l[index]<l[i]){
index=i;
}
}
return l[index];
}
int main(){
int t;
cin>>t;
while(t--){
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
l[i]=1;
}
cout<<f()<<endl;
if(t)cout<<endl;
}
}
7-23 最长公共子序列长度
#include<iostream>
using namespace std;
const int m = 100;
char a[m];
char b[m];
int d[m][m];
int main() {
cin >> a;
int la = 0;
for (char i : a) {
if (i != NULL)la++;
else break;
}
cin >> b;
int lb = 0;
for (char i : b) {
if (i != NULL)lb++;
else break;
}
for (int i = 0; i < m; i++) {
d[i][0] = 1;
d[0][i] = 1;
}
for (int i = 0; i < la; i++) {
for (int j = 0; j < lb; j++) {
if (a[i] != b[j]) {
d[i + 1][j + 1] = max(d[i][j + 1], d[i + 1][j]);
}
else {
d[i + 1][j + 1] = d[i][j] + 1;
}
}
}
cout << d[la][lb]-1;
return 0;
}
7-24 0-1背包
#include<iostream>
using namespace std;
int f[1001];
int v[105];
int w[105];
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>w[i]>>v[i];
}
for(int i=1;i<=n;i++){
for(int j=m;j>=w[i];j--){
f[j]=max(f[j],f[j-w[i]]+v[i]);
}
}
cout<<f[m];
return 0;
}
7-25 最优二叉搜索树
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<cmath>
using namespace std;
const int M = 100;
double C[M][M], W[M][M], p[M], q[M];
int S[M][M];
int n, i, j, k;
void Optimal_BST()
{
for (i = 1; i <= n; i++)
{
C[i][i - 1] = 0.0;
W[i][i - 1] = q[i - 1];
}
for (int t = 1; t <= n; t++)
{
for (i = 1; i <= n - t + 1; i++)
{
j = i + t - 1;
W[i][j] = W[i][j - 1] + p[j] + q[j];
C[i][j] = C[i][i - 1] + C[i + 1][j];
S[i][j] = i;
// 选取i+1到j之间的某个下标的关键字作为i到j的根,如果组成的期望值最小
// 则k为i到j的根结点
for (k = i + 1; k < j; k++)
{
double tmp = C[i][k - 1] + C[k + 1][j];
if (tmp < C[i][j] && fabs(tmp - C[i][j])>1E-6)
{
C[i][j] = tmp;
S[i][j] = k; // 记录i到j结点的树根
}
}
C[i][j] += W[i][j];
}
}
}
void Construct_Optimal_BST(int i, int j, bool flag)
{
if (flag == 0)
{
cout << S[i][j] << " ";;
flag = 1;
}
int k = S[i][j];
// 如果左子树是叶子
if (k - 1 < i)
{
cout << "." << " ";;
}
else
{
cout << S[i][k - 1] << " ";;
Construct_Optimal_BST(i, k - 1, 1);
}
// 如果右子树是叶子
if (k >= j)
{
cout << "." << " ";;
}
else
{
cout << S[k + 1][j] << " ";;
Construct_Optimal_BST(k + 1, j, 1);
}
}
int main()
{
cin >> n;
for (i = 1; i <= n; i++)
{
cin >> p[i];
}
for (i = 0; i <= n; i++)
{
cin >> q[i];
}
Optimal_BST();
cout << fixed << setprecision(2) << C[1][n] << endl;
Construct_Optimal_BST(1, n, 0);
system("pause");
return 0;
}
7-26 选课(贪心)
#include<iostream>
#include<algorithm>
using namespace std;
const int m = 10009;
pair<double,double> a[m];
char b[m];
int cmp(pair<double, double> a, pair<double, double>b) {
return a.second < b.second;
}
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> b;
cin >> a[i].first;
cin >> a[i].second;
}
sort(a, a+n, cmp);
int ans = 1;
double j = a[0].second;
for (int i = 1; i < n; i++) {
if (a[i].first >= j) {
j = a[i].second;
ans += 1;
}
}
cout << ans << endl;
return 0;
}
7-27 汉密尔顿回路
#include<bitset>
#include<iostream>
#include<cstring>
using namespace std;
int a[210][210];
int b[210];
int c[210];
int main() {
int n, m;
cin >> n >> m;
//输入边
for (int i = 0; i < m; i++) {
int x, y;
cin >> x >> y;
a[x][y] = a[y][x]= 1;
}
int p;
cin >> p;
//int v = 0;
while (p--) {
int q;//一次测验几个点检验
cin >> q;
bool flag = true;
//memset(c, false, sizeof(c));
memset(c, 0, sizeof(c));
for (int i = 1; i < q; i++) {
int t;
cin >> t;
b[i] = t;
if (t<1 || t>n) {
flag = false;
//cout << "不合格点" << endl;
}
if (c[t] == 1) {
//cout << "有重复的" << endl;
flag = false;
}
c[t]=1;
}
cin >> b[q];
//没有走过所有点
if (q != n + 1)flag = false;
//cout << "访问数组c为:";
//for (int i = 1; i <= q; i++) {
// cout << c[i] << " ";
//}
//cout << endl;
//cout << "输入数组为:" ;
//for (int i = 1; i <= q; i++) {
// cout << b[i] << " ";
//}
//cout << endl;
//检验是否有0
if (b[1] != b[q]) {
//cout << "首尾不一样" << endl;
flag = false;
}
for (int i = 2; i <= q; i++) {
if (a[b[i]][b[i-1]] != 1) {
flag = false;
//cout << "有不连通的两个点" << endl;
}
}
//cout << flag ? "YES" : "NO" << endl;
if (flag) {
cout << "YES" << endl;
}
else {
cout << "NO" << endl;
}
}
return 0;
}
7-28 八皇后问题(*)
#include<iostream>
#include<algorithm>
using namespace std;
int n, * x; //x[]皇后在每一行的位置
bool b=false; //判断有没有解
bool constraint(int k)
{
for (int j = 0; j < k; j++)
if ((abs(x[j] - x[k]) == abs(j - k)) || (x[j] == x[k])) //判断是否在同一斜线或同一列
return false;
return true;
}
void backtrack(int k)
{
int i;
if (k >= n)
{
if(b)
cout<<endl;
b = true;
for (int j, i = 0; i < n; i++)
{
for (j = 0; j < n-1; j++)
{
if (x[i] == j)
cout << "Q ";
else cout << ". ";
}
if (x[i] == j)
cout << "Q";
else cout << ".";
cout << endl;
}
}
else
{
for (i = 0; i < n; i++)
{
x[k] = i;
if (constraint(k))
backtrack(k + 1);
}
}
}
int main()
{
cin >> n;
x = new int[n];
backtrack(0);
if (!b)
cout << "None" << endl;
delete[] x;
return 0;
}
7-29 任务分配
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
int n;
const int INF=0x3f3f3f3f;
const int mn=21;
int a[mn][mn];
int ans=INF;
class node{
public:
int r;
int c;
int l;
bool w[mn];
bool operator<(const node&s)const{
return l>s.l;
}
};
void b(node & e){
int m=0;
for(int i=e.r+1;i<=n;i++){
int nmin=INF;
for(int j=1;j<=n;j++){
if(e.w[j]==false&&nmin > a[i][j]){
nmin=a[i][j];
}
}
m+=nmin;
}
e.l=e.c+m;
}
void bfs(){
node e,e1;
e.c=0;
memset(e.w,0,sizeof(e.w));
e.r=0;
b(e);
priority_queue<node>q;
q.push(e);
while(!q.empty()){
e=q.top();
q.pop();
if(e.r==n){
if(ans>e.c){
ans=e.c;
}
}
e1.r=e.r+1;
for(int i=1;i<=n;i++){
if(e.w[i]){
continue;
}
for(int j=1;j<=n;j++){
e1.w[j]=e.w[j];
}
e1.w[i]=true;
e1.c=e.c+a[e1.r][i];
b(e1);
if(e1.l<ans){
q.push(e1);
}
}
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
}
}
bfs();
cout<<ans<<endl;
return 0;
}
7-30 吉林跑男
判断是否是二分图(是NO,否YES)
#include<bits/stdc++.h>
using namespace std;
const int maxn=10000005;
int father[maxn];
int findset(int x)//并查集路径压缩
{
if(x!=father[x]) father[x]=findset(father[x]);
return father[x];
}
int main(){
int t;
cin>>t;
while(t--){
int n,m;
cin>>n>>m;
for(int i=1;i<=2*n;i++) father[i]=i;
bool flag=true;
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
int fa=findset(u);//查找根节点
int fb=findset(v);
int x=findset(u+n);//查找u不认识的人的根节点
int y=findset(v+n);
if(fa==fb) flag=false;
else//将两个不认识的人合并在同一个集合中
{
father[x]=fb;
father[y]=fa;
}
}
if(flag) printf("NO\n");
else printf("YES\n");
}
return 0;
}