26daoti转载

1302: 【入门】挛生素数
#include <bits/stdc++.h>
using namespace std;
int n;
//判断x是否为质数 
bool check(int x)
{
    for(int i=2; i<=sqrt(x); ++i){
        if(x%i==0){
            return false;
        }
    } 
    return true;
}
int main()
{
    scanf("%d", &n);
    for(int i=2; i<=n-2; ++i){
        if(check(i) && check(i+2)){
            printf("%d %d\n", i, i+2);
        }
    }
    return 0;
}
1087: 【入门】哥德巴赫猜想
#include <bits/stdc++.h>
using namespace std;
int n, total, prim[200];
//判断x是否为质数 
bool check(int x)
{
    for(int i=2; i<=sqrt(x); ++i){
        if(x%i==0){
            return false;
        }
    } 
    return true;
}
int main()
{
    scanf("%d", &n);
    for(int i=2; i<=n; ++i){
        if(check(i)){
            total++;
            prim[total]=i;
        }
    }
    for(int i=4; i<=n; i+=2){
        //将i分解为两个质数的和
        for(int j=1; j<=total; ++j){
            for(int k=j; k<=total; ++k){
                if(i==prim[j]+prim[k]){
                    printf("%d=%d+%d\n", i, prim[j], prim[k]); 
                }
            }
        } 
    }
    return 0;
}
1100: 【入门】等差素数组
#include <bits/stdc++.h>
using namespace std;
int n, total, mid, prim[100];
bool vis[100];
//判断x是否为质数 
bool check(int x)
{
    for(int i=2; i<=sqrt(x); ++i){
        if(x%i==0){
            return false;
        }
    } 
    return true;
}
int main()
{
    //先求出100以内的质数 
    for(int i=2; i<=100; ++i){
        if(check(i)){
            total++;    //总共有total个质数 
            prim[total]=i;
            vis[i]=true;    //将质数标记为true 
        }
    }
    for(int i=1; i<total; ++i){    //枚举质数 
        for(int j=i+1; j<=total; ++j){    //枚举后面的质数 
            if((prim[i]+prim[j])%2){    //如果两个质数之和不是偶数, 直接跳过 
                continue;
            }
            mid=(prim[i]+prim[j])/2;    //计算平均值 
            if(vis[mid]){    //如果平均值也是质数, 则输出 
                printf("%d %d %d\n", prim[i], mid, prim[j]);
            }
        } 
    }
    return 0;
}
1097: 【入门】素数回文数
#include <bits/stdc++.h>
using namespace std;
//判断x是否为质数 
bool check(int x)
{
    for(int i=2; i<=sqrt(x); ++i){
        if(x%i==0){
            return false;
        }
    } 
    return true;
}
//判断一个数是否是回文数 
bool palindromic(int x)
{
    int length=0, num[4];    //length记得初始化 
    //数位分离, 将每一位保存在数组中 
    while(x){
        length++;
        num[length]=x%10;
        x/=10;
    } 
    for(int i=1; i<=length; ++i){
        if(num[i]!=num[length-i+1]){
            return false;
        }
    }
    return true;
}
int main()
{
    for(int i=10; i<=1000; ++i){
        if(check(i) && palindromic(i)){
            printf("%d\n", i);
        }
    }
    return 0;
}
1076: 【基础】机器人的逻辑
#include <bits/stdc++.h>
using namespace std;
int n, a[51];
bool flag;
int main()
{
    scanf("%d", &n);
    for(int i=1; i<=n; ++i){
        scanf("%d", &a[i]);
    }
    sort(a+1, a+n+1); 
    for(int i=a[1]; i>=1; --i){
        flag=true;
        for(int j=1; j<=n; ++j){
            if(a[j]%i!=0){
                flag=false;
                break;
            }
        }
        if(flag==true){
            printf("%d", i);
            return 0;
        }
    }
    return 0;
}
1140: 【基础】亲密数对
#include <bits/stdc++.h>
using namespace std;
int n;
//计算x的因子之和 
int sum(int x)
{
    int asd=0;
    for(int i=2; i<=sqrt(x); ++i){
        //如果i是x的因子 
        if(x%i==0){
            asd+=i;
            asd+=x/i;    
        }
        if(i*i==x){
            asd-=i;
        }
    } 
    return asd;
}
int main()
{
    scanf("%d", &n);
    for(int i=2; i<=n; ++i){
        int temp=sum(i);
        if(temp!=i && sum(temp)==i && temp<=n){
            printf("%d %d\n", i, temp);
        } 
    }
    return 0;
}
2000: 【基础】因子游戏
#include <bits/stdc++.h>
using namespace std;
int k, a[81];
//计算x的因子之和 
int sum(int x)
{
    int asd=0;
    for(int i=1; i<=sqrt(x); ++i){
        //如果i是x的因子 
        if(x%i==0){
            asd+=2;    
        }
        if(i*i==x){
            asd--;
        }
    } 
    return asd;
}
//输出x的约数 
void print(int x)
{
    printf("%d\n", x);
    for(int i=1; i<=x; ++i){
        //如果i是x的因子 
        if(x%i==0){
            printf("%d ", i);
        }
    } 
}
int main()
{
    scanf("%d", &k);
    for(int i=1; i<=20000; ++i){
        if(sum(i)==k){ 
            print(i);
            return 0; 
        } 
    }
    printf("NO SOLUTION");
    return 0;
}
1153: 【基础】经典递归问题——汉诺塔
#include <bits/stdc++.h>
using namespace std;
int n, cnt;
void asd(int n, char a, char b, char c)
{
    if(n==1){
        printf("%c To %c\n", a, c);
        cnt++;
    }
    else{
        asd(n-1, a, c, b);
        printf("%c To %c\n", a, c);
        cnt++;
        asd(n-1, b, a, c);
    }
}
int main()
{
    scanf("%d", &n);
    asd(n, 'A', 'B', 'C');
//    printf("最少步数为:%d", cnt);
    return 0;
}
2801: 【基础】聪明的海宝
#include <bits/stdc++.h>
using namespace std;
int n;
//计算第w个沙坑中的金币数 
int ans(int w)
{
    if(w==1){
        return 1;
    }
    //偶数 
    if(w%2==0){
        return ans(w/2)+w; 
    }
    else{    //奇数 
        return ans(3*w+1)+w; 
    }
}
int main()
{
    scanf("%d", &n);
    printf("%d", ans(n));
    return 0;
}
1844: 【USACO】Symmetry(对称)
#include <bits/stdc++.h>
using namespace std;
int n, m;
int solve(int x, int y)
{
    //有一个是偶数, 就没有中心格子了 
    if(x%2==0 || y%2==0){
        return 0; 
    }
    else{    //找到一个中心格子, 并继续划分 
        return 1+4*solve(x/2, y/2); 
    }
}
int main()
{
    scanf("%d %d", &n, &m);
    printf("%d", solve(n, m));
    return 0;
}
1571: 【NOIP98普及组】2的幂次方
方法一:递归
#include <bits/stdc++.h>
using namespace std;
int n;
void solve(int x)
{
    int flag=-1;
    int cnt=0, a[20];
    memset(a, 0, sizeof(a));
    //先对x进行二进制拆分
    //将十进制x转换为二进制
    while(x){
        a[cnt]=x%2;     //从a[0]开始保存最低位 
        if(x%2!=0 && flag==-1){
            flag=cnt;    //flag表示二进制数非0的最低位
        }
        x>>=1;    //幂运算, 相当于x/=2; 
        cnt++;
    } 
    //从最高位开始, 对非0项进行递归输出 
    for(int i=cnt-1; i>=0; --i){
        if(a[i]==0){
            continue;
        } 
        else{
            if(i==0){    //已经到最低位了, 2的0次直接输出, 递归出口 
                printf("2(0)");
                return;
            }
            else if(i==1){    //2的1次, 题目要求直接输出2 
                printf("2");    //注意, 此时不能直接return, 有可能还有2的0次 
                if(i>flag){        //判断, 如果此时不是最低位, 则需要输出+ 
                    printf("+");
                }
            }
            else{    //一路递归下去 
                printf("2(");  
                solve(i);    //递归函数要放在中间 
                printf(")");
                if(i>flag){        //判断, 如果此时不是最低位, 则需要输出+ 
                    printf("+");
                }    
            } 
        }
    }
}
int main()
{
    scanf("%d", &n);
    solve(n);    
    return 0;
}
方法二:打表
#include <iostream>
using namespace std;
int n, a[100], length, cnt;
//打表 
string s[17]={"0", "", "2", "2+2(0)", "2(2)", "2(2)+2(0)", "2(2)+2", "2(2)+2+2(0)", "2(2+2(0))", "2(2+2(0))+2(0)", "2(2+2(0))+2",
              "2(2+2(0))+2+2(0)", "2(2+2(0))+2(2)", "2(2+2(0))+2(2)+2(0)", "2(2+2(0))+2(2)+2", "2(2+2(0))+2(2)+2+2(0)", "2(2(2))"};
int main()
{
    cin >> n;
    //将十进制数n转换为二进制数,存在a数组中,a[0]存低位
    //length记录二进制有几位 
    while(n){
        a[length]=n%2;
        n/=2;
        length++;
    }
    //计算转换后的二进制中有多少个1,也就是最后的式子中有cnt-1个加号 
    for(int i=0; i<length; ++i){
        if(a[i]!=0){
            cnt++; 
        }
    }
    cnt--;
    //将二进制中位数为1的位输出 
    for(int i=length-1; i>=0; --i){
        //位数为1,并且不是2^1那一位 
        if(a[i]!=0 && i!=1){
            cout << "2(" << s[i] << ")";
            if(cnt!=0){    //如果这个式子后面还有式子,则输出一个加号 
                cout << "+";
                cnt--;
            }
        }
        else if(a[i]!=0 && i==1){ //位数为1,并且是2^1那一位 
            cout << "2";
            if(cnt!=0){    //如果这个式子后面还有式子,则输出一个加号
                cout << "+";
                cnt--;
            }
        }
    }
 
    return 0;
}
2342: 【提高】递归
#include <bits/stdc++.h>
using namespace std;
long long a, b, c, ans[21][21][21];
long long w(long long x, long long y, long long z)
{
    if(x<=20 && y<=20 && z<=20 && x>=0 && y>=0 && z>=0 && ans[x][y][z]){
        return ans[x][y][z];
    }
    if(x<=0 || y<=0 || z<=0){
        return 1;
    }
    else if(x>20 || y>20 || z>20){
        return w(20, 20, 20);
    }
    else if(x<y && y<z){
        return ans[x][y][z]=w(x,y,z-1)+w(x,y-1,z-1)-w(x,y-1,z);
    }
    else{
        return ans[x][y][z]=w(x-1,y,z)+w(x-1,y-1,z)+w(x-1,y,z-1)-w(x-1,y-1,z-1);
    }
}
int main()
{
    while(1){
        scanf("%lld %lld %lld", &a, &b, &c);
        if(a==-1 && b==-1 && c==-1){
            return 0;
        }
        memset(ans, 0, sizeof(ans));
        printf("w(%lld, %lld, %lld) = %lld\n", a, b, c, w(a, b, c));
    }
    return 0;

1091: 【提高】那些n位数
方法一:循环
//循环方法 
#include <bits/stdc++.h>
using namespace std;
int n, p;
int main()
{
    scanf("%d %d", &n, &p);
    if(n==1){
        for(int i=1; i<=p; ++i){
            printf("%d\n", i);
        }
    }
    else if(n==2){
        for(int i=1; i<=p; ++i){
            for(int j=1; j<=p; ++j){
                printf("%d%d\n", i, j);
            }
        }
    }
    else if(n==3){
        for(int i=1; i<=p; ++i){
            for(int j=1; j<=p; ++j){
                for(int k=1; k<=p; ++k){
                    printf("%d%d%d\n", i, j, k);
                }
            }
        }
    }
    else if(n==4){
        for(int i=1; i<=p; ++i){
            for(int j=1; j<=p; ++j){
                for(int k=1; k<=p; ++k){
                    for(int l=1; l<=p; ++l){
                        printf("%d%d%d%d\n", i, j, k, l);
                    }
                }
            }
        }    
    }
    else if(n==5){
        for(int i=1; i<=p; ++i){
            for(int j=1; j<=p; ++j){
                for(int k=1; k<=p; ++k){
                    for(int l=1; l<=p; ++l){
                        for(int m=1; m<=p; ++m){
                            printf("%d%d%d%d%d\n", i, j, k, l, m);
                        }
                    }
                }
            }
        }
    }
    else if(n==6){
        for(int i=1; i<=p; ++i){
            for(int j=1; j<=p; ++j){
                for(int k=1; k<=p; ++k){
                    for(int l=1; l<=p; ++l){
                        for(int m=1; m<=p; ++m){
                            for(int o=1; o<=p; ++o){
                                printf("%d%d%d%d%d%d\n", i, j, k, l, m, o);
                            }    
                        }
                    }
                }
            }
        }
    }
    else if(n==7){
        for(int i=1; i<=p; ++i){
            for(int j=1; j<=p; ++j){
                for(int k=1; k<=p; ++k){
                    for(int l=1; l<=p; ++l){
                        for(int m=1; m<=p; ++m){
                            for(int o=1; o<=p; ++o){
                                for(int q=1; q<=p; ++q){
                                    printf("%d%d%d%d%d%d%d\n", i, j, k, l, m, o, q);
                                }
                            }    
                        }
                    }
                }
            }
        }
    }
    else if(n==8){
        for(int i=1; i<=p; ++i){
            for(int j=1; j<=p; ++j){
                for(int k=1; k<=p; ++k){
                    for(int l=1; l<=p; ++l){
                        for(int m=1; m<=p; ++m){
                            for(int o=1; o<=p; ++o){
                                for(int q=1; q<=p; ++q){
                                    for(int r=1; r<=p; ++r){
                                        printf("%d%d%d%d%d%d%d%d\n", i, j, k, l, m, o, q, r);
                                    }
                                }
                            }    
                        }
                    }
                }
            }
        }
    }
    return 0;
}
方法二:递归
#include <bits/stdc++.h>
using namespace std;
int n, p, a[10];
void solve(int cnt)
{
    if(cnt==n+1){
        for(int i=1; i<=n; ++i){
            printf("%d", a[i]);
        }
        printf("\n");
        return;
    }
    for(int i=1; i<=p; ++i){
        a[cnt]=i;
        solve(cnt+1);
    }
}
int main()
{
    scanf("%d %d", &n, &p);
    solve(1);
    return 0;
}
2023: 【提高】那些n位数II
#include <bits/stdc++.h>
using namespace std;
int n, p, a[10];
bool vis[10];
void solve(int cnt)
{
    if(cnt==n+1){
        for(int i=1; i<=n; ++i){
            printf("%d", a[i]);
        }
        printf("\n");
        return;
    }
    for(int i=1; i<=p; ++i){
        if(vis[i]==false){
            a[cnt]=i;    
            vis[i]=true;
            solve(cnt+1);
            vis[i]=false;
        }
    }
}
int main()
{
    scanf("%d %d", &n, &p);
    solve(1);
    return 0;
}
2025: 【提高】生成组合
方法一:循环
//循环方法 
#include <bits/stdc++.h>
using namespace std;
int n, p;
int main()
{
    scanf("%d %d", &p, &n);
    if(n==1){
        for(int i=1; i<=p; ++i){
            printf("%d\n", i);
        }
    }
    else if(n==2){
        for(int i=1; i<=p; ++i){
            for(int j=i+1; j<=p; ++j){
                printf("%d%d\n", i, j);
            }
        }
    }
    else if(n==3){
        for(int i=1; i<=p; ++i){
            for(int j=i+1; j<=p; ++j){
                for(int k=j+1; k<=p; ++k){
                    printf("%d%d%d\n", i, j, k);
                }
            }
        }
    }
    else if(n==4){
        for(int i=1; i<=p; ++i){
            for(int j=i+1; j<=p; ++j){
                for(int k=j+1; k<=p; ++k){
                    for(int l=k+1; l<=p; ++l){
                        printf("%d%d%d%d\n", i, j, k, l);
                    }
                }
            }
        }    
    }
    else if(n==5){
        for(int i=1; i<=p; ++i){
            for(int j=i+1; j<=p; ++j){
                for(int k=j+1; k<=p; ++k){
                    for(int l=k+1; l<=p; ++l){
                        for(int m=l+1; m<=p; ++m){
                            printf("%d%d%d%d%d\n", i, j, k, l, m);
                        }
                    }
                }
            }
        }
    }
    else if(n==6){
        for(int i=1; i<=p; ++i){
            for(int j=i+1; j<=p; ++j){
                for(int k=j+1; k<=p; ++k){
                    for(int l=k+1; l<=p; ++l){
                        for(int m=l+1; m<=p; ++m){
                            for(int o=m+1; o<=p; ++o){
                                printf("%d%d%d%d%d%d\n", i, j, k, l, m, o);
                            }    
                        }
                    }
                }
            }
        }
    }
    else if(n==7){
        for(int i=1; i<=p; ++i){
            for(int j=i+1; j<=p; ++j){
                for(int k=j+1; k<=p; ++k){
                    for(int l=k+1; l<=p; ++l){
                        for(int m=l+1; m<=p; ++m){
                            for(int o=m+1; o<=p; ++o){
                                for(int q=o+1; q<=p; ++q){
                                    printf("%d%d%d%d%d%d%d\n", i, j, k, l, m, o, q);
                                }
                            }    
                        }
                    }
                }
            }
        }
    }
    else if(n==8){
        for(int i=1; i<=p; ++i){
            for(int j=i+1; j<=p; ++j){
                for(int k=j+1; k<=p; ++k){
                    for(int l=k+1; l<=p; ++l){
                        for(int m=l+1; m<=p; ++m){
                            for(int o=m+1; o<=p; ++o){
                                for(int q=o+1; q<=p; ++q){
                                    for(int r=q+1; r<=p; ++r){
                                        printf("%d%d%d%d%d%d%d%d\n", i, j, k, l, m, o, q, r);
                                    }
                                }
                            }    
                        }
                    }
                }
            }
        }
    }
    else if(n==9){
        for(int i=1; i<=p; ++i){
            for(int j=i+1; j<=p; ++j){
                for(int k=j+1; k<=p; ++k){
                    for(int l=k+1; l<=p; ++l){
                        for(int m=l+1; m<=p; ++m){
                            for(int o=m+1; o<=p; ++o){
                                for(int q=o+1; q<=p; ++q){
                                    for(int r=q+1; r<=p; ++r){
                                        for(int s=r+1; s<=p; ++s){
                                            printf("%d%d%d%d%d%d%d%d%d\n", i, j, k, l, m, o, q, r, s);
                                        }
                                    }
                                }
                            }    
                        }
                    }
                }
            }
        }
    }
    return 0;
}
方法二:递归
#include <iostream>
using namespace std;
int n, r;
int a[21];
void dfs(int cnt)
{
    if(cnt==r+1){
        for(int i=1; i<=r; i++)
            printf("%d", a[i]);
        printf("\n");
        return;
    }
    for(int i=a[cnt-1]+1; i<=n-r+cnt; i++){        //n-r+cnt写成n也可以 
        a[cnt]=i;     
        dfs(cnt+1);
    }
}
int main()
{
    cin >> n >> r;
    dfs(1);
    return 0;
}
1648: 【提高】素数个数
#include <bits/stdc++.h>
using namespace std;
int n, r;
int num[21], a[21], sum, ans;
bool check(int x)
{
    if(x<2){
        return false;
    }
    for(int i=2; i<=sqrt(x); ++i){
        if(x%i==0){
            return false;
        }
    }
    return true;
}
void dfs(int cnt)
{
    if(cnt==r+1){
        sum=0;
        for(int i=1; i<=r; i++)
            sum+=num[a[i]];
        if(check(sum)){
            ans++;
        }
        return;
    }
    for(int i=a[cnt-1]+1; i<=n-r+cnt; i++){        //n-r+cnt写成n也可以 
        a[cnt]=i;     
        dfs(cnt+1);
    }
}
int main()
{
    scanf("%d %d", &n, &r);
    for(int i=1; i<=n; ++i){
        scanf("%d", &num[i]);
    }
    dfs(1);
    printf("%d", ans);
    return 0;
}
2026: 【提高】自然数拆分
#include <bits/stdc++.h>
using namespace std;
int n, a[15], num;
struct node
{
    int asd[15];
    int tot;
    long long id;    
}ans[100];
bool cmp(node x, node y)
{
    return x.id>y.id; 
}
//将x分为total个整数, 当前准备分第cnt个整数 
void dfs(int x, int cnt, int total)
{
    //将x分为total个数, 现在准备安排第cnt个, 如果第cnt个等于total 
    if(cnt==total){    //如果要将x分为一个数, 直接赋值为x 
        if(x<a[cnt-1])    return;        //避免重复 
        a[cnt]=x;
        num++;
        ans[num].tot=total;
        for(int i=total; i>=1; --i){
            ans[num].asd[i]=a[i];
            ans[num].id+=a[i]*pow(10,n+i-total);
        }
    }
    else{
        //还没分完, 如果分的是第一个, 则从1开始枚举, 此时的a[cnt-1]为0
        //如果分的不是第一个, 则从前一个值开始枚举 
        for(int i=max(1, a[cnt-1]); i<=x; ++i){
            a[cnt]=i;
            dfs(x-i, cnt+1, total);
        }
    }
    

int main()
{
    scanf("%d", &n);
    for(int i=1; i<=n; ++i){
        //将n分为i个整数之和, 当前准备分安排第一个 
        dfs(n, 1, i);    
    }
    sort(ans+1, ans+num+1, cmp);
    for(int i=1; i<=num; ++i){
        for(int j=ans[i].tot; j>=1; --j){
            printf("%3d", ans[i].asd[j]);
        } 
        printf("\n");
    }
    return 0;
}
2027: 【提高】自然数拆分II
#include <bits/stdc++.h>
using namespace std;
int n, a[15], num;
struct node
{
    int asd[15];
    int tot;
    long long id;    
}ans[100];
bool cmp(node x, node y)
{
    return x.id<y.id; 
}
//将x分为total个整数, 当前准备分第cnt个整数 
void dfs(int x, int cnt, int total)
{
    //将x分为total个数, 现在准备安排第cnt个, 如果第cnt个等于total 
    if(cnt==total){    //如果要将x分为一个数, 直接赋值为x 
        if(x<a[cnt-1])    return;        //避免重复 
        a[cnt]=x;
        num++;
        ans[num].tot=total;
        for(int i=1; i<=total; ++i){
            ans[num].asd[i]=a[i];
            ans[num].id+=a[i]*pow(10,n-i);
        }
    }
    else{
        //还没分完, 如果分的是第一个, 则从1开始枚举, 此时的a[cnt-1]为0
        //如果分的不是第一个, 则从前一个值开始枚举 
        for(int i=max(1, a[cnt-1]); i<=x; ++i){
            a[cnt]=i;
            dfs(x-i, cnt+1, total);
        }
    }
    

int main()
{
    scanf("%d", &n);
    for(int i=2; i<=n; ++i){
        //将n分为i个整数之和, 当前准备分安排第一个 
        dfs(n, 1, i);    
    }
    sort(ans+1, ans+num+1, cmp);
    for(int i=1; i<=num; ++i){
        for(int j=1; j<=ans[i].tot; ++j){
            printf("%3d", ans[i].asd[j]);
        } 
        printf("\n");
    }
    return 0;
}
1494: 【USACO】"跳房子"
#include <bits/stdc++.h>
using namespace std;
int a[10][10], ans;
bool vis[1000000];
//跳到了x行y列, 当前是第cnt个数, 此前的和为cur 
void dfs(int x, int y, int cnt, int cur)
{
    //跳到界外 
    if(x<1 || y<1 || x>5 || y>5){
        return;
    }
    if(cnt==6){    //已经是第6个数了 
        //累加
        cur=cur*10+a[x][y];
        if(vis[cur]==false){
            ans++;
            vis[cur]=true;
        }
        return;
    } 
    else{    //还没跳够6个数 
        cur=cur*10+a[x][y]; 
        dfs(x-1, y, cnt+1, cur);
        dfs(x+1, y, cnt+1, cur);
        dfs(x, y-1, cnt+1, cur);
        dfs(x, y+1, cnt+1, cur);
    }
}
int main()
{
    for(int i=1; i<=5; ++i){
        for(int j=1; j<=5; ++j){
            scanf("%d", &a[i][j]);
        } 
    }
    for(int i=1; i<=5; ++i){
        for(int j=1; j<=5; ++j){
            dfs(i, j, 1, 0);
        } 
    }
    printf("%d", ans); 
    return 0;

1666: 【基础】发书
#include <bits/stdc++.h>
using namespace std;
int k, n, m, from, to;
//n<250,m<10000
//这道题数据范围有问题, 数组开到250会出错, 改为251就过了 
bool vis[251], flag;
bool know[251][251];
void dfs(int id)
{
    for(int i=1; i<=n; ++i){
        //如果id认识i, 并且还没给i发书 
        if(know[id][i] && !vis[i]){
            vis[i]=true;
            //让i去发书 
            dfs(i);
        }
    }
}
int main()
{
    //k代表star的学号,n代表人数,m代表关系数
    scanf("%d %d %d", &k, &n, &m);
    while(m--){
        scanf("%d %d", &from, &to);
        know[from][to]=true;
    }
    vis[k]=true;
    dfs(k);
    for(int i=1; i<=n; ++i){
        if(!vis[i]){
            printf("%d ", i);
            flag=true;
        }
    } 
    if(flag==false){
        printf("0");
    }
    return 0;

1168: 【提高】老鼠闯迷宫
#include <bits/stdc++.h>
using namespace std;
int m, n;
int a[20][20];    //1表示有障碍物 
int ans[200][3];    //ans[i][1]表示第i步的行, ans[i][2]表示第i步的列 
bool vis[20][20];    //标记是否走过 
int mx[9]={0, 1, 0, -1, -1, -1, 0, 1, 1};
int my[9]={0, 1, 1, 1, 0, -1, -1, -1, 0}; 
void dfs(int x, int y, int cnt)
{
    //出界 或者 有障碍物 
    if(x<1 || y<1 || x>m || y>n || a[x][y]==1){
        return;
    }
    //到达终点 
    if(x==m && y==n){
        //输出路径 
        ans[cnt][1]=x;
        ans[cnt][2]=y;
        for(int i=1; i<=cnt; ++i){
            printf("(%d,%d)", ans[i][1], ans[i][2]);
            if(i!=cnt){
                printf("-");
            }
        }
        exit(0);    //结束程序 
    }
    //还没到达终点
    ans[cnt][1]=x;
    ans[cnt][2]=y;
    //标记 
    vis[x][y]=true;
    for(int i=1; i<=8; ++i){
        int xx=x+mx[i];
        int yy=y+my[i];
        if(!vis[xx][yy]){
            dfs(xx, yy, cnt+1);
        }
    } 
    //回溯 
    vis[x][y]=false;
}
int main()
{
    //m行n列 
    scanf("%d %d", &m, &n);
    for(int i=1; i<=m; ++i){    //行 
        for(int j=1; j<=n; ++j){    //列 
            scanf("%d", &a[i][j]);    //1表示有障碍物 
        }
    }
    vis[1][1]=true;
    //从第一行第一列出发, 走了一个格子 
    dfs(1, 1, 1); 
    return 0;    

1167: 【提高】跳马
//这道题关于输出的描述有问题, 题目描述输出一条路径,
//实际需要输出所有的路径, 每行一条 
#include <bits/stdc++.h>
using namespace std;
int m, n;
int a[20][20];    //1表示有障碍物 
int ans[200][3];    //ans[i][1]表示第i步的行, ans[i][2]表示第i步的列 
bool vis[20][20];    //标记是否走过 
int mx[9]={0, 2, 1, -1, -2, -2, -1, 1, 2};
int my[9]={0, 1, 2, 2, 1, -1, -2, -2, -1}; 
void dfs(int x, int y, int cnt)
{
    //出界 或者 有障碍物 
    if(x<1 || y<1 || x>m || y>n || a[x][y]==1){
        return;
    }
    //到达终点 
    if(x==m && y==n){
        //输出路径 
        ans[cnt][1]=x;
        ans[cnt][2]=y;
        for(int i=1; i<=cnt; ++i){
            printf("(%d,%d)", ans[i][1], ans[i][2]);
            if(i!=cnt){
                printf("-");
            }
        }
        printf("\n");
//        exit(0);    //结束程序 
        return; 
    }
    //还没到达终点
    ans[cnt][1]=x;
    ans[cnt][2]=y;
    //标记 
    vis[x][y]=true;
    for(int i=1; i<=8; ++i){
        int xx=x+mx[i];
        int yy=y+my[i];
        if(!vis[xx][yy]){
            dfs(xx, yy, cnt+1);
        }
    } 
    //回溯 
    vis[x][y]=false;
}
int main()
{
    //m行n列 
    scanf("%d %d", &m, &n);
    for(int i=1; i<=m; ++i){    //行 
        for(int j=1; j<=n; ++j){    //列 
            scanf("%d", &a[i][j]);    //1表示有障碍物 
        }
    }
    vis[1][1]=true;
    //从第一行第一列出发, 走了一个格子 
    dfs(1, 1, 1); 
    return 0;    

1846: 【USACO】Space Exploration
#include <bits/stdc++.h>
using namespace std;
int n;
char a[1002][1002];
bool vis[1002][1002];
int ans;
void dfs(int x, int y)
{
    if(a[x+1][y]=='*' && !vis[x+1][y]){
        vis[x+1][y]=true;
        dfs(x+1, y);
    }
    if(a[x-1][y]=='*' && !vis[x-1][y]){
        vis[x-1][y]=true;
        dfs(x-1, y);
    }
    if(a[x][y+1]=='*' && !vis[x][y+1]){
        vis[x][y+1]=true;
        dfs(x, y+1);
    }
    if(a[x][y-1]=='*' && !vis[x][y-1]){
        vis[x][y-1]=true;
        dfs(x, y-1);
    }
}
int main()
{
    scanf("%d", &n);
    for(int i=1; i<=n; ++i){
        for(int j=1; j<=n; ++j){
            cin >> a[i][j];
        }
    }
    for(int i=1; i<=n; ++i){
        for(int j=1; j<=n; ++j){
            //i行j列为岛屿, 并且没被其他岛屿包含进去 
            if(a[i][j]=='*' && !vis[i][j]){
                ans++;
                dfs(i, j);
            } 
        }
    }
    printf("%d", ans);
    return 0;    

1495: 【USACO】卫星照片
#include <bits/stdc++.h>
using namespace std;
int w, h;
char a[1002][82];
bool vis[1002][82];
int cur, ans;
void dfs(int x, int y)
{
    if(a[x+1][y]=='*' && !vis[x+1][y]){
        vis[x+1][y]=true;
        cur++;
        dfs(x+1, y);
    }
    if(a[x-1][y]=='*' && !vis[x-1][y]){
        vis[x-1][y]=true;
        cur++;
        dfs(x-1, y);
    }
    if(a[x][y+1]=='*' && !vis[x][y+1]){
        vis[x][y+1]=true;
        cur++;
        dfs(x, y+1);
    }
    if(a[x][y-1]=='*' && !vis[x][y-1]){
        vis[x][y-1]=true;
        cur++;
        dfs(x, y-1);
    }
}
int main()
{
    scanf("%d %d", &w, &h);
    for(int i=1; i<=h; ++i){
        for(int j=1; j<=w; ++j){
            cin >> a[i][j];    //字符数组输入用cin 
        }
    }
    for(int i=1; i<=h; ++i){
        for(int j=1; j<=w; ++j){
            //i行j列为牧场, 并且没被其他牧场包含进去 
            if(a[i][j]=='*' && !vis[i][j]){
                vis[i][j]=true;
                //每次找牧场时初始化当前这片牧场的面积 
                cur=1;
                dfs(i, j);
                //找完与i行j列连续的牧场, 更新答案 
                ans=max(ans, cur);
            } 
        }
    }
    printf("%d", ans);
    return 0;    

2028: 【提高】8皇后问题
方法一

#include <bits/stdc++.h>
using namespace std;
//a[i]存的是第i行的棋子放的列,我们的目标就是把1-n分配给a[1]-a[n],并且不能冲突 
//vis[i][j]=1表示第i行第j列放了棋子,为0表示没放棋子
//vis1[i]=1表示第i列有棋子了,为0表示第i列没有棋子 
int n, a[14], vis[14][14], vis1[14];
//在x行y列放会不会产生冲突 
bool ok(int x, int y)
{
    //定义临时遍历,不然x,y的值在一次while判断后就改变了,导致后面的判断失效 
    int tempx, tempy;    
    //判断同一行、同一列有没有冲突 
    //其实没有必要判断行(因为每行只安排一个数),没有必要判断列(vis1[i]表示第i列有没有数字) 
    /*
    for(int i=1; i<=n; ++i){
        if(vis[x][i]==1 || vis[i][y]==1){
            return false;
        }
    }
    */
    tempx=x;
    tempy=y;
    //判断左下角有没有冲突 
    while(tempx!=n && tempy!=1){
        tempx++;
        tempy--;
        if(vis[tempx][tempy]==1){
            return false;
        }
    }
    tempx=x;
    tempy=y;
    //判断右上角有没有冲突 
    while(tempx!=1 && tempy!=n){
        tempx--;
        tempy++;
        if(vis[tempx][tempy]==1){
            return false;
        }
    } 
    tempx=x;
    tempy=y;
    //判断左上角有没有冲突 
    while(tempx!=1 && tempy!=1){
        tempx--;
        tempy--;
        if(vis[tempx][tempy]==1){
            return false;
        }
    }
    tempx=x;
    tempy=y;
    //判断右下角有没有冲突 
    while(tempx!=n && tempy!=n){
        tempx++;
        tempy++;
        if(vis[tempx][tempy]==1){
            return false;
        }
    }  
    return true;
}
void dfs(int cnt)
{
    if(cnt==n+1){
        for(int i=1; i<=n; ++i){
            cout << a[i] << " ";
        }
        cout << endl;    
    }
    //看第cnt行要放在第几列,i遍历列 
    for(int i=1; i<=n; ++i){
        //如果第cnt行第i列没有放棋子,并且第i列没有放棋子
        //并且在cnt行i列放棋子不会产生冲突,才可以放 
        if(vis[cnt][i]==0 && vis1[i]==0 && ok(cnt, i)){    
            vis[cnt][i]=1;
            vis1[i]=1;
            a[cnt]=i;    
            dfs(cnt+1);
            vis[cnt][i]=0;    
            vis1[i]=0;            
        }
    }
}
int main()
{
    n=8;
    dfs(1);
    return 0;
}
方法二

1154: 【基础】N皇后问题
#include <bits/stdc++.h>
using namespace std;
//a[i]存的是第i行的棋子放的列,我们的目标就是把1-n分配给a[1]-a[n],并且不能冲突 
//vis[i][j]=1表示第i行第j列放了棋子,为0表示没放棋子
//vis1[i]=1表示第i列有棋子了,为0表示第i列没有棋子 
int n, a[14], vis[14][14], vis1[14];
//在x行y列放会不会产生冲突 
bool ok(int x, int y)
{
    //定义临时遍历,不然x,y的值在一次while判断后就改变了,导致后面的判断失效 
    int tempx, tempy;    
    //判断同一行、同一列有没有冲突 
    //其实没有必要判断行(因为每行只安排一个数),没有必要判断列(vis1[i]表示第i列有没有数字) 
    /*
    for(int i=1; i<=n; ++i){
        if(vis[x][i]==1 || vis[i][y]==1){
            return false;
        }
    }
    */
    tempx=x;
    tempy=y;
    //判断左下角有没有冲突 
    while(tempx!=n && tempy!=1){
        tempx++;
        tempy--;
        if(vis[tempx][tempy]==1){
            return false;
        }
    }
    tempx=x;
    tempy=y;
    //判断右上角有没有冲突 
    while(tempx!=1 && tempy!=n){
        tempx--;
        tempy++;
        if(vis[tempx][tempy]==1){
            return false;
        }
    } 
    tempx=x;
    tempy=y;
    //判断左上角有没有冲突 
    while(tempx!=1 && tempy!=1){
        tempx--;
        tempy--;
        if(vis[tempx][tempy]==1){
            return false;
        }
    }
    tempx=x;
    tempy=y;
    //判断右下角有没有冲突 
    while(tempx!=n && tempy!=n){
        tempx++;
        tempy++;
        if(vis[tempx][tempy]==1){
            return false;
        }
    }  
    return true;
}
void dfs(int cnt)
{
    if(cnt==n+1){
        for(int i=1; i<=n; ++i){
            for(int j=0; j<=n; ++j){
                if(j==a[i]){
                    cout << " Q";
                }
                else if(j==0){
                    printf("%2d", n-i+1); 
                }
                else{
                    cout << "  ";
                }
            }
            cout << endl;
        }
        printf("   a");    
        for(int i=1; i<=n-1; ++i){
            printf("%2c", 'a'+i);
        }
        cout<<endl<<endl;
    }
    //看第cnt行要放在第几列,i遍历列 
    for(int i=1; i<=n; ++i){
        //如果第cnt行第i列没有放棋子,并且第i列没有放棋子
        //并且在cnt行i列放棋子不会产生冲突,才可以放 
        if(vis[cnt][i]==0 && vis1[i]==0 && ok(cnt, i)){    
            vis[cnt][i]=1;
            vis1[i]=1;
            a[cnt]=i;    
            dfs(cnt+1);
            vis[cnt][i]=0;    
            vis1[i]=0;            
        }
    }
}
int main()
{
    cin >> n;
    dfs(1);
    return 0;
}
1313: 【USACO】城堡
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值