PAT A 1065 1066 1067 1068

1065

permutation 排列
题目大意: 给三个数A,B,C,范围在[-2^63, 2^63],判断是否a+b>c ;
思路: 借这题来复习各个数据类型的范围。

数据类型 用10表示 用2表示
unsigned int
int
unsigned long
long
long long
unsigned long long

顺便复习一下精度

数据类型 比特位数 有效数字 用10表示 用2表示
float 32 6~7
double 64 15~16 ——
long double 128 18~19 ——
#include
using namespace std;
int main(){
    int t;
    cin>>t;
    for(int i=1;i<=t;i++){
        long double a, b, c;
        cin>>a>>b>>c;
        if(a+b>c){
            cout<<"Case #"<

1066 AVL树建树

题目大意: 给出插入序列,找到AVL树的根节点

#include
#include
using namespace std;

struct node{
    int val;
    struct node *left, *right;
};

int getheight(node *root){
    if(root == NULL) return 0;
    return max(getheight(root->left), getheight(root->right)) + 1;
}

node *rotater(node *root){
    node *t = root->left;
    root->left = t->right;
    t->right = root;
    return t;
}

node *rotatel(node *root){
    node *t = root->right;
    root->right = t->left;
    t->left = root;
    return t;
}

node *rotatelr(node *root){
    root->left = rotatel(root->left);
    return rotater(root);
}

node *rotaterl(node *root){
    root->right = rotater(root->right);
    return rotatel(root);
}

node *insert(node *root, int v){
    if(root == NULL){
        root = new node();
        root->val = v;
        root->left = root->right = NULL;
    }else if(root->val < v){
        root->right = insert(root->right, v);
        if(getheight(root->left)-getheight(root->right) == -2){
            root = v > root->right->val ? rotatel(root) : rotaterl(root);
        }
    }else{
        root->left = insert(root->left,v);
        if(getheight(root->left)-getheight(root->right) == 2){
            root = v < root->left->val ? rotater(root) : rotatelr(root);
        }
    }
    return root;
}

int main(){
    int n, x;
    cin>>n;
    node *root = NULL;
    for(int i=0;i>x;
        root = insert(root, x);
    }
    cout<val<

1067 贪心

题目大意: 每次只能调换序列中0和另外一个数字。求为了将序列从小到大排序,至少要调换几次
思路: 0 在哪个位置上,就让0和那个数字交换

#include
using namespace std;

int main(){
    int n,x;
    cin>>n;
    int a[100005];
    for(int i=0;i>x;
        a[x] = i;
    }
    int count = 0;
    for(int i = 0; i < n; i++){
        if(a[i] == i) continue;
        while(a[0]!=0){
            swap(a[0], a[a[0]]);
            count++;
        }
        if(i!=a[i]){
            swap(a[0],a[i]);
            count++;
        }
    } 
    cout<

1068 动态规划

题目大意: 用n个硬币买价值为m的东西,输出使用方案,并将方案从小到大排列,输出最小的那个排列方案。
思路: 背包问题,最后输出的是每次都选择较小的硬币,然后让使用的硬币序列最长。纳了闷了,说好的数据小于等于10^4,开10005的数组有段错误,改成10010就没有了??? 一开始做的时候 测试点3 错误,将数组拿到main外就对了,因为全局变量在静态存储区分配内存,局部变量是在栈上分配内存空间。如果数组太大,可能会造成栈溢出

#include
#include
#include
using namespace std;

int w[10010], dp[10010];
bool choice[10010][110];

bool cmp(int a,int b){
    return a>b;
}

int main(){
    int n, m; //硬币总数<=10^4 、需要付的钱 <=100
    cin>>n>>m;
    
    for(int i=1;i<=n;i++){
        cin>>w[i];
    } 
    
    //将硬币从大到小排序 
    sort(w+1, w+n+1,cmp);
    
    for(int i = 1;i <= n; i++){
        for(int j = m; j >= w[i]; j--){
            if(dp[j] <= dp[j-w[i]] + w[i]){
                choice[i][j] = true;
                dp[j] = dp[j-w[i]] + w[i];
            }
        }
    }
    if(dp[m] != m) cout<<"No Solution";
    else{
        vector ans;
        int v = m, index = n;
        while(v>0){
            if(choice[index][v] == true){
                ans.push_back(w[index]);
                v -= w[index];
            }
            index--;
        }
        for(int i=0; i < ans.size(); i++){
            if( i != 0) cout<<" ";
            cout<

你可能感兴趣的:(PAT A 1065 1066 1067 1068)