pat 1065 A+B and C                                         

主要是注意一下加法溢出的情况,不要试图使用double,因为它的精度是15~16位,不能满足精度要求,代码如下:

 #include<cstdio>
#include<climits>
#include<cmath>
//double精度为15~16位,不能满足精度要求
int main()
{
int testNum;
scanf("%d",&testNum);
long long MAX = LONG_LONG_MAX; //pow(2,63) - 1,
long long MIN = LONG_LONG_MIN; //-1*pow(2,63);
for(int i = ; i <= testNum; i++)
{
long long a,b,c;
scanf("%lld %lld %lld", &a, &b, &c); if(a >= && b >=)
{
if(MAX - a >= b)
goto NORMAL;
else
{
printf("Case #%d: true\n", i);
continue;
}
}
else if(a < && b < )
{
if(MIN - a <= b)
goto NORMAL;
else
{
printf("Case #%d: false\n", i);
continue;
}
}
else ; NORMAL:
if(a + b > c)
printf("Case #%d: true\n", i);
else
printf("Case #%d: false\n", i);
}
return ;
}

pat 1066 Root of AVL Tree                                          本文地址

最基本的AVL树的操作,关于AVL树可以参考herehere,代码如下:

 #include<cstdio>
#include<climits>
#include<cmath> //operate of AVL tree inline int max2(int a, int b)
{
return a>b? a:b;
} struct avlnode
{
struct avlnode *rson;
struct avlnode *lson;
int data;
int height;
}; inline int height(struct avlnode *tree)
{
if(NULL == tree)
return -;
else return tree->height;
} void rotateR(struct avlnode * &root)
{
struct avlnode *proot = root;
root = root->lson;
proot->lson = root->rson;
root->rson = proot;
proot->height = max2(height(proot->lson), height(proot->rson)) + ;
root->height = max2(height(root->lson), height(root->rson)) + ;
} void rotateL(struct avlnode * &root)
{
struct avlnode * proot = root;
root = root->rson;
proot->rson = root->lson;
root->lson = proot;
proot->height = max2(height(proot->lson), height(proot->rson)) + ;
root->height = max2(height(root->lson), height(root->rson)) + ;
} void rotateRL(struct avlnode * &root)
{
rotateR(root->rson);
rotateL(root);
} void rotateLR(struct avlnode * &root)
{
rotateL(root->lson);
rotateR(root);
} void insertAVL(struct avlnode * &root, int data)
{
if(root == NULL)
{
root = new struct avlnode;
root->data = data;
root->lson = NULL;
root->rson = NULL;
root->height = ;
return;
} if(data < root->data)
{
insertAVL(root->lson, data);
if( == height(root->lson) - height(root->rson))
{
if(data < root->lson->data)
rotateR(root);
else rotateLR(root);
}
}
else
{
insertAVL(root->rson, data);
if(- == height(root->lson) - height(root->rson))
{
if(data > root->rson->data)
rotateL(root);
else
{
rotateRL(root);
}
}
}
root->height = max2(height(root->lson), height(root->rson)) + ;
} int main()
{
int N;
scanf("%d", &N);
struct avlnode *root = NULL;
for(int i = ; i <= N; i++)
{
int data;
scanf("%d", &data);
insertAVL(root,data);
}
printf("%d", root->data);
return ;
}

pat 1067 Sort with Swap(0,*)                                     本文地址

首先找出不在正确位置上的数字的个数N,假设每次交换都把一个元素放到了正确的位置则至少需要N-1次交换(最后一次交换把两个元素放到了正确的位置)。

但是在交换的过程中若0被交换到了第一个位置,那么下一次交换不会把一个元素交换到正确位置,即要做一次额外的交换。因此我们要知道整个过程中0几次被交换到了第一个位置,当输入序列和排序好的序列中存在一个循环时,0就会被交换到第一个位置一次:

如0 1 2 3 4
   4 0 3 2 1 该序列存在2个循环 0-4-4-1-1-0,2-3-3-2 ,0被交换到了第一个位置2次,但是最后一次是刚好把0归为,因此交换次数为N-1+(2-1)。

因此最终交换次数是:N-1+循环个数-1

考虑到一个特殊情况:当0开始就在第一个位置时,我们开始就需要把他交换到某个循环中(和某个不在正确位置的数交换),这样交换次数+1,交换后不在正确位置的元素个数增加了一个,N也需要+1,,即总的交换次数+2。

代码如下:

 #include<cstdio>
int main()
{
int N,*arry;
scanf("%d", &N);
arry = new int[N];
bool *flag = new bool[N];
int swaptimes = -;
for(int i = ; i < N; i++)
{
scanf("%d", &arry[i]);
if(arry[i] == i)flag[i] = true;
else
{
flag[i] = false;
swaptimes++;
}
}
if(swaptimes == -)
{
printf("");
return ;
} if(flag[] == true)
swaptimes += ;
for(int i = ; i < N; i++)
{
int k = arry[i];
if(flag[k] == false)
{
//找到一个循环
swaptimes++;
while(flag[k] == false)
{
flag[k] = true;
k = arry[k];
}
} }
printf("%d", swaptimes - );
delete []arry;
delete []flag;
return ;
}

pat 1068 Find More Coins                                       本文地址

典型的0-1背包问题,关于0-1背包的讲解可参考Cui Tianyi大神的背包九讲

  • 本题动态规划方程:f[i][v] = max{ f[i-1][v],  f[i-1][v-coins[i]]+coins[i] } ,f[i][v]表示前i枚硬币能拼凑出不超过v的最大金额,v代表的是一个金额,coins[i]代表第i个硬币的面额;
  • 由于题目还要求输出最小字典序,可以先对硬币按面值递减排序,并且在程序中,当f[i-1][v] = f[i-1][v-coins[i]]+coins[i] 时,我们选择后者,因为后者倾向于选择排在后面的硬币,越选择排在后面的硬币,结果序列的字典序越小。(开始我误认为先对硬币从小到大排序,然后当f[i-1][v] = f[i-1][v-coins[i]]+coins[i] 时,选择前者也可以得到正确答案,实验证明这是错误的,因为选择前者的意思是倾向于尽量不选择大面值的硬币,但是这样并不等价于结果序列的字典序小,比如2 3 4比1 3 5 的字典序大,但是1 3 5却选择了更大的面值5)
  • 对于最后结果序列的输出,我们用数组path[i][j]保存结果,path[i][j]=true表示凑足价格 j 时,使用了前 i 个硬币中的第 i 个,false表示没有使用,最后可以从path中逆推结果,具体见代码

代码如下:

 #include<cstdio>
#include<algorithm> int main()
{
//freopen("input.txt", "r", stdin);
int coinNum, needPay;
scanf("%d%d", &coinNum, &needPay);
int coins[coinNum+];
for(int i = ; i <= coinNum; i++)
scanf("%d", &coins[i]);
//f[i][j] 表示前 i 枚硬币能拼凑出的小于等于 j 的最大值(j 这里代表一个价格)
int f[coinNum+][needPay+];
//path[i][j]=true表示凑足价格j时,使用了第i个硬币,false表示没有使用
bool path[coinNum+][needPay+];
for(int i = ; i <= coinNum; i++)//初始化
for(int j = ; j <= needPay; j++)
{
f[i][j] = ;
path[i][j] = false;
}
std::sort(coins+, coins+coinNum+, std::greater<int>());
for(int i = ; i <= coinNum; i++)
for(int j = coins[i]; j <= needPay; j++)
{
if(f[i-][j] <= f[i-][j-coins[i]] + coins[i])
{
f[i][j] = f[i-][j-coins[i]] + coins[i];
path[i][j] = true;
}
else
{
f[i][j] = f[i-][j];
path[i][j] = false;
}
}
if(f[coinNum][needPay] != needPay)
printf("No Solution\n");
else
{//从path中恢复解
int tmp = needPay, i = coinNum;
while(tmp > )
{
if(path[i][tmp] == true)
{
printf("%d", coins[i]);
tmp -= coins[i];
if(tmp > )
printf(" ");
}
i--;
}
}
return ;
}

对于该题,对于数据规模不大时,可以用递归解法,比如问题 “1...n个硬币凑足价格p” 可以分为 “2...n个硬币凑足价格p-coin[1]” 和"2...n个硬币凑足价格p",即分为第一个硬币选择或者不选两种情。对于结果要求最小字典序,先将硬币按面值从小到大排序,分解问题时,先求第一个硬币选择时的子问题。1068的递归代码如下,但是最后一个测试数据超时,不知道是因为代码有问题还是数据规模太大,如果大家找出了问题,请留言,谢谢!

 #include<cstdio>
#include<algorithm> bool gatherCoinRecur(int money, int coins[], int n, int start, bool choose[])
{
if(money == )return true;
else if(money < )return false;
if(start >= n)return false;
choose[start] = true;
if(gatherCoinRecur(money - coins[start], coins, n, start+, choose))
return true;
choose[start] = false;
if(gatherCoinRecur(money, coins, n, start+, choose))
return true;
return false;
} int main()
{
freopen("input.txt", "r", stdin);
int coinNum, needPay;
scanf("%d%d", &coinNum, &needPay);
int coins[coinNum];
bool choose[coinNum];
for(int i = ; i < coinNum; i++)
{
scanf("%d", &coins[i]);
choose[i] = false;
}
std::sort(coins, coins+coinNum);
if(gatherCoinRecur(needPay, coins, coinNum, , choose))
{
int i = ;
while(choose[i] == false)i++;
printf("%d", coins[i]);
for(i++; i < coinNum; i++)
if(choose[i])printf(" %d", coins[i]);
}
else printf("No Solution\n");
return ;
}

【版权声明】转载请注明出处:http://www.cnblogs.com/TenosDoIt/p/3406776.html

PAT 1065 1066 1067 1068的更多相关文章

  1. PAT甲级1066. Root of AVL Tree

    PAT甲级1066. Root of AVL Tree 题意: 构造AVL树,返回root点val. 思路: 了解AVL树的基本性质. AVL树 ac代码: C++ // pat1066.cpp : ...

  2. PAT 1065 - 1068 题解

    这次的题目来源是 2013 年 10 月 7 日下午的浙大计算机研究生招生机试题. 这次题目的难度,按姥姥的说法是:『比普通的 PAT 要难了 0.5 个点.我是把自己的题目从 1.0 到 5.0 以 ...

  3. PAT 1065 A+B and C (64bit) (20)

    1065. A+B and C (64bit) (20) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 HOU, Qiming G ...

  4. PAT 1065 A+B and C (64bit)

    1065 A+B and C (64bit) (20 分)   Given three integers A, B and C in [−], you are supposed to tell whe ...

  5. PAT 乙级 1066 图像过滤(15) C++版

    1066. 图像过滤(15) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 图像过滤是把图像中不重要的像素都染成 ...

  6. PAT甲题题解-1068. Find More Coins (30)-dp,01背包

    一开始没多想,虽然注意到数据N<=10^4的范围,想PAT的应该不会超时吧,就理所当然地用dfs做了,结果最后一组真的超时了.剪枝啥的还是过不了,就意识到肯定不是用dfs做了.直到看到别人说用0 ...

  7. PAT 1065 单身狗(25)(STL-map+思路+测试点分析)

    1065 单身狗(25 分) "单身狗"是中文对于单身人士的一种爱称.本题请你从上万人的大型派对中找出落单的客人,以便给予特殊关爱. 输入格式: 输入第一行给出一个正整数 N(≤  ...

  8. PAT 1065 A+B and C[大数运算][溢出]

    1065 A+B and C (64bit)(20 分) Given three integers A, B and C in [−2​63​​,2​63​​], you are supposed t ...

  9. pat 甲级 1066. Root of AVL Tree (25)

    1066. Root of AVL Tree (25) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue An A ...

随机推荐

  1. Windows XP Manifest in Delphi

    Find out how you can include the manifest into a Delphi project to allow your application to share t ...

  2. IOS 内存斗争小史之 对象、指针、内存的基本理解

    1.指针和对象,都是内存块.一个大,一个小.一个在栈中,一个在堆中. 2.iOS中,我们可以生命一个指针,也可以通过alloc获取一块内存. 3.我们可以直接消灭掉一个指针,将其置为nil.但是我们没 ...

  3. ubuntu下安装android sdk运行模拟器出现错误:

    ./emulator: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No ...

  4. Java 单例模式的常见应用场景

    单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的抽象,而单例模式只有自己一个对象,也因此 ...

  5. 同志亦凡人第一季/全集BQueer As Folk 1迅雷下载

    同志亦凡人 第一季 Queer as Folk Season 1 (2000) 本季看点:本剧叙述一群同志男女在美国匹兹堡的生活,剧情重心由原来三位男主角Brian,Michael,Justin之间的 ...

  6. Hyperledger 项目

    https://github.com/hyperledger/fabric.githttps://github.com/hyperledger/blockchain-explorer.githttps ...

  7. SeekBar的用法和自定义滑块的样式

    SeekBar继承自ProgressBar,所以基本一样,我们自定义一般也就是顶一个滑块的图片而已. 布局文件 <RelativeLayout xmlns:android="http: ...

  8. List集合中的数据按照某一个属性进行分组

    有的时候,我们需要在java中对集合中的数据进行分组运算.例如:Bill对象有money(float)和type(String)属性,现有个集合List<Bill>,需要按照Bill的ty ...

  9. linux文件去重工具findup, fslint-gui

    findup, fslint-gui,图形化工具,直接使用

  10. [转]pear windows 安装

    FROM : http://jingyan.baidu.com/article/ca41422fd8cf3d1eae99ed3e.html 因为想使用phpdocument生成文档,不得不安装pear ...