PAT A 1128 1129 1130 1131

1128

8皇后问题:任意两个皇后不能在同一个竖线、横线、斜线上
判断是否是N皇后成立

#include<stdio.h>
#include<math.h>
int main(){
    int k;
    scanf("%d", &k);
    for(int i=0;i<k;i++){
        int n;
        scanf("%d", &n);
        int a[1005];
        bool table[1005] = {false};
        bool flag = true;
        for(int j=1;j<=n;j++){
            scanf("%d", &a[j]);
            if(table[a[j]] == false){//检查是否有在同一列的 
                table[a[j]] = true;
            }else{
                flag = false;
                //printf("1 ");
            }
        }
        for(int p=1;p<=n;p++){//检查是否在一个对角线 
            for(int q=p+1;q<=n;q++){
                if(abs(p-q) == abs(a[p]-a[q])){
                    flag = false;
                    break;
                } 
            }
        }
        if(flag) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
} 

1129 STL

题目大意: 根据物品被用户接受的次数来计算推荐指数。
一开始用的map,因为map的值不好排序,又转化到vector,再用sort排序。这样会超时。

#include<stdio.h>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;

typedef struct node{
    int id;
    int count;
}node;

bool cmp(node a, node b){
    if(a.count == b.count){
        return a.id < b.id;
    }
    return a.count > b.count;
}

int main(){
    int n,k;
    scanf("%d %d", &n, &k);
    int q;
    scanf("%d", &q);
    map<int, int> mp;
    mp[q]++;
    for(int i=1;i<n;i++){
        scanf("%d", &q);
        printf("%d:",q);
        vector<node> v;
        map<int, int>::iterator iter;
        for(iter = mp.begin(); iter!=mp.end();iter++){
            node temp;
            temp.id = iter->first;
            temp.count = iter->second;
            v.push_back(temp);
        }
        sort(v.begin(), v.end(), cmp);
        for(int j=0;j<k && j<i;j++){
            printf(" %d",v[j].id);
        }
        mp[q]++;
        printf("\n");
    }
    return 0;
} 

参考柳婼 の blog,应该重载set运算符:

#include <iostream>
#include <set>
using namespace std;
int book[50001];
struct node {
    int value, cnt;
    bool operator < (const node &a) const {
        return (cnt != a.cnt) ? cnt > a.cnt : value < a.value;
    }
};
int main() {
    int n, k, num;
    scanf("%d%d", &n, &k);
    set<node> s;
    for (int i = 0; i < n; i++) {
        scanf("%d", &num);
        if (i != 0) {
            printf("%d:", num);
            int tempCnt = 0;
            for(auto it = s.begin(); tempCnt < k && it != s.end(); it++) {
                printf(" %d", it->value);
                tempCnt++;
            }
            printf("\n");
        }
        auto it = s.find(node{num, book[num]});
        if (it != s.end()) s.erase(it);
        book[num]++;
        s.insert(node{num, book[num]});
    }
    return 0;
}

1130 中缀表达式

题目大意: 给出二叉树,输出中缀表达式 ,并加上括号表示运算的优先级

  • syntax:语法
  • parentheses:圆括号
  • precedences:优先

题目中说 data is a string of no more than 10 characters
当我数组设为10时就出现了运行时错误,将数组范围扩大到15就全对了。。

#include<vector>
#include<string.h>
#include<string>
#include<iostream>
using namespace std;

typedef struct node{
    char data[15];
    int left,right;
}node;

int n;
vector<node> v;
bool table[100] = {false};
string ans = "";
int root;

void inorder(int x){
    if(v[x].left != -1){
        if( x!= root ) ans += "(";
        inorder(v[x].left);
    }else if(v[x].right != -1 && x!= root){
        ans += "(";
    }
    ans += v[x].data;
    if(v[x].right != -1){
        inorder(v[x].right);
        if( x!= root ) ans += ")";
    }
    return;
}

int main(){
    cin>>n;
    v.resize(n+5);
    for(int i=1;i<=n;i++){
        char d[15];
        int l,r;
        cin>>d>>l>>r;
        strcpy(v[i].data, d);
        v[i].left = l;
        v[i].right = r;
        table[l] = table[r] = true;
    }
    //首先找到根节点 
    for(int i=1; i<=n; i++){
        if(table[i] == false){
            root = i;
            break;
        }
    } 
    inorder(root);
    cout<<ans;
    return 0;
}

1131 DFS

题目大意: 给出乘客的起点,找到途经停站最少的路线;如果经停站一样多,则取需要换乘线路次数最少的路线。

  • 站点可能成圈
  • 没有单个站点作为线路
  • 不同线路无重复的一段路线
  • 每个站点最多同时在5条线路上
#include<stdio.h>
#include<vector>
#include<map>
#include<string>
using namespace std;

typedef struct node{
    int line;  //属于哪条线路
    int id;  //下一个站点名 
}node;

int n;  //n<=100  地铁线数
int start, endd;
map<int, bool> mp;
vector< vector<node> > v(10000);
int min_stations, min_lines;
vector<node> temp;//记录路径
vector<node> ans;//记录最终路径 

void dfs(node x, int stations, int lines, int old_line){
    if(mp[x.id] == true){
        return;
    }
    if(x.id == endd){
        if(x.line != old_line){
            lines++;
        }
        bool flag = false;
        if(stations < min_stations){
            min_stations = stations;
            min_lines = lines;
            flag = true;
        }else if(stations == min_stations && lines < min_lines){
            min_lines = lines;
            flag = true;
        }
        if(flag){
            ans.clear();
            node t;
            t.id = start;
            t.line = -1;
            ans.push_back(t);
            for(int i=0;i<temp.size();i++){
                ans.push_back(temp[i]);
            }
            ans.push_back(x);
        }
        return;
    }
    mp[x.id] = true;
    temp.push_back(x);
    if(x.line != old_line){
        lines++;
    }
    for(int i=0;i<v[x.id].size();i++){
        dfs(v[x.id][i], stations+1, lines, x.line);
    }
    mp[x.id] = false;
    temp.pop_back();
}

int main(){
    scanf("%d", &n);
    for(int i=1;i<=n;i++){
        int m;  //m<=100 站点数
        scanf("%d", &m);
        int st;
        scanf("%d", &st);
        for(int j=1;j<m;j++){
            int end;
            scanf("%d", &end);
            node temp;
            temp.id = end;
            temp.line = i;
            v[st].push_back(temp);
            temp.id = st;
            v[end].push_back(temp);
            st = end;
        }
    }
    int k;  //k<=10  query
    scanf("%d", &k); 
    for(int i=0;i<k;i++){
        scanf("%d %d", &start, &endd);
        min_stations = 99999, min_lines = 999;
        mp.clear();
        mp[start] = true;
        for(int j=0;j<v[start].size();j++){
            dfs(v[start][j], 1, 1, v[start][j].line);
        }
        printf("%d\n", min_stations);
        int first = start;
        for(int j=1;j<ans.size();j++){
            if(ans[j-1].line != ans[j].line && j != 1){
                printf("Take Line#%d from %04d to %04d.\n", ans[j-1].line, first, ans[j-1].id);
                first = ans[j-1].id;
            }
        }
        printf("Take Line#%d from %04d to %04d.\n", ans[ans.size()-1].line, first, ans[ans.size()-1].id);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值