个人学习记录,代码难免不尽人意。
呃,这次得了89分,居然排名排到了当年的119名,满分的居然有72个之多,真让人不敢相信。我感觉主要是思路的问题,我有些题没有想到最优解,并且有些细节可能忽略了导致没有满分。第四题很重要,需要再复习复习如何判断一个树是不是满二叉树、完全二叉树的方法。
Balloon popping is a fun game for kids. Now n balloons are positioned in a line. The goal of the game is very simple: to pop as many balloons as possible. Here we add a special rule to this game – that is, you can only make ONE jump. Assume that a smart baby covers his/her body by thorns(刺), jumps to some position and lies down (as shown by the figures below), so that the balloons will be popped as soon as they are touched by any part of the baby’s body. Now it is your job to tell the baby at which position he/she must jump to pop the most number of balloons.
Input Specification:
Each input file contains one test case. For each case, two positive integers are given in the first line: n (≤10 5 ), the number of balloons in a line, and h (≤10 3 ), the height of the baby with his/her arms stretched up. Then n integers are given in the next line, each corresponds to the coordinate of a balloon on the axis of the line. It is guaranteed that the coordinates are given in ascending order, and are all in the range [−10 6
,10 6 ].
Output Specification:
Output in a line the coordinate at which the baby shall jump, so that if the baby jumps at this position and then lie down, the maximum number of the balloons can be popped beneath his/her body. Then also print the maximum number of balloons that can be popped. If the coordinate is not unique, output the smallest one.
The numbers must be separated by 1 space, and there must be no extra space at the beginning or the end of the line.
Sample Input:
11 120
-120 -40 0 80 122 140 160 220 240 260 300
Sample Output:
120 5
Note: jumping at any position from 120 to 140, or from 240 to 260 can pop 5 balloons, hence 120 is printed as the smallest one.
#include
#include
#include
#include
using namespace std;
const int maxn=1000100;
int list[maxn];
int main(){
int n,length;
scanf("%d %d",&n,&length);
for(int i=0;i<n;i++){
scanf("%d",&list[i]);
}
int pos=0,count=0;
for(int i=0;i<n;i++){
int temp=0;
int j=i;
for(j;j<n;j++){
if(list[j]-list[i]<=length){
temp++;
}
else{
break;
}
}
j--;
if(count<temp){
count=temp;
pos=list[j]-length;
}
}
cout << pos << " "<<count;
}
这道题说实话一开始没有想到会这么简单~就是很简单双重循环判断。
7-2 The Second Run of Quicksort
“During the sorting, processing every element which is not yet at its final position is called a run. Which of the following cannot be the result after the second run of quicksort?” – This is a question in the Graduate Entrance Exam set. Now you are supposed to write a program to check the answers automatically.
Input Specification:
Each input file contains several test cases. The first line gives a positive integer K (≤10), which is the total number of cases. Then K cases are given in the fomat
N
a[0] a[1] … a[N-1]
where N (3≤N≤10 5) is the number of elements, and a[i]'s (≤10 9) are distinct elements to be checked. All the numbers in a line are positive integers that are separated by spaces.
Output Specification:
For each test case, output in a line Yes if it is possible to be the second run of quicksort, or No if not.
Sample Input:
4
8
5 2 16 12 28 60 32 72
8
2 16 5 28 12 60 32 72
8
2 12 16 5 28 32 72 60
8
5 2 12 28 16 32 72 60
Sample Output:
Yes
Yes
Yes
No
Hint:
Case 1 is possible because we may choose 72 to be the pivot during the first run, and 28 to be the pivot during the second run.
Case 2 is possible because we may choose 2 to be the pivot during the first run, and 72 to be the pivot during the second run, or vice versa.
Case 3 is possible because we may choose 28 to be the pivot during the first run, 2 and 32 to be the pivots for the left- and right-hand side subsequences during the second run, respectively.
Case 4 is impossible because if we choose 12 to be the pivot during the first run, then the left-hand side subsequence would have no pivot; or if we choose 32 to be the pivot during the first run, then the right-hand side subsequence would have no pivot.
17分代码
#include
#include
#include
#include
using namespace std;
bool judge(int left,int right,int mid,int num[]){
bool flag=true;
for(int i=left;i<mid;i++){
if(num[i]>num[mid]){
flag=false;
break;
}
}
for(int i=mid+1;i<=right;i++){
if(num[i]<num[mid]){
flag=false;
break;
}
}
return flag;
}
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
int k;
scanf("%d",&k);
int num[k];
for(int j=0;j<k;j++){
scanf("%d",&num[j]);
}
bool flag=false;
for(int j=0;j<k;j++){
if(judge(0,k-1,j,num)){
bool flag1=true;
bool flag2=true;
for(int p=0;p<j;p++){
if(judge(0,j-1,p,num)){
flag1=true;
break;
}
if(p==j-1) flag1=false;
}
for(int p=j+1;p<k;p++){
if(judge(j+1,k-1,p,num)){
flag2=true;
break;
}
if(p==k-1) flag2=false;
}
if(flag1&&flag2){
flag=true;
printf("Yes\n");
break;
}
}
}
if(!flag){
printf("No\n");
}
}
}
这道题想复杂了! 我思路是对的,但是这样做后面两个测试点会超时。想要简化我们需要知道,每一次快排会确定当前区间某一个元素的位置;如果三个以上元素位置确定 或 两个元素位置确定并且包含第一个元素或最后一个元素中的其中一个,则为快排第二趟后的序列。
7-3 Leader of the Opinion Leaders
Sample Input:
10 3
3 9 3 8
2 1 3
2 9 7
3 2 7 5
3 6 3 7
2 7 3
1 2
2 3 9
1 10
1 3
Sample Output:
7 9
22分代码
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn=10100;
struct node{
int cnt;
int index;
int flag;
};
set<int> s;
vector<int> follow[maxn],leader;
vector<node> res;
int in[maxn]={0};
int out[maxn]={0};
bool cmp(node a,node b){
if(a.flag==0||b.flag==0) return a.flag>b.flag;
else if(a.cnt!=b.cnt) return a.cnt>b.cnt;
else return a.index<b.index;
}
int main(){
int n,t;
scanf("%d %d",&n,&t);
for(int i=1;i<=n;i++){
int len;
scanf("%d",&len);
for(int j=0;j<len;j++){
int num;
scanf("%d",&num);
follow[i].push_back(num);
in[num]++;
out[i]++;
}
node no;
no.cnt=0;
no.flag=0;
no.index=i;
res.push_back(no);
}
for(int i=1;i<=n;i++){
if((int)in[i]/out[i]>=t){
s.insert(i);
leader.push_back(i);
}
}
// for(int i=0;i
// cout << leader[i]<
// }
// for(set::iterator it=s.begin();it!=s.end();it++){
// cout <<*it<
// }
for(int i=0;i<leader.size();i++){
for(int j=0;j<follow[leader[i]].size();j++){
if(s.find(follow[leader[i]][j])!=s.end()){
res[follow[leader[i]][j]-1].flag=1;
res[follow[leader[i]][j]-1].cnt++;
}
}
}
// cout <
// for(int i=0;i
// cout << res[i].index << " "<
// }
sort(res.begin(),res.end(),cmp);
int temp=res[0].cnt;
printf("%d",res[0].index);
for(int i=1;i<res.size();i++){
if(res[i].cnt==temp&&res[i].flag==1){
printf(" %d",res[i].index);
}
else break;
}
}
说实话这道题我看了很久都不知道为什么扣了3分,如果读者有心可以帮我检查一下,我佛了。
7-4 Pseudo-completeness
In computer science, a perfect binary tree is a binary tree in which all non-leaf nodes have two children and all leaves have the same depth. In a complete binary tree, every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. A pseudo-complete binary tree is a binary tree that becomes a perfect tree when the bottom level is removed.
Given the inorder and preorder traversal sequences of a binary tree, you are supposed to tell the type of this tree, and output its postorder traversal sequence.
Input Specification:
Each input file contains one test case. The first line gives a positive integer N (≤2000) which is the number of nodes in the tree. Then the following two lines contain the inorder and preorder traversal sequences of the binary tree, respectively. It is guaranteed that all the keys are distinct, and in the range of int. All the numbers in a line are separated by a space.
Output Specification:
For each test case, first print in a line the type of the given tree: 1 for perfect binary tree, 2 for complete binary tree (but not of type 1), 3 for pseudo-complete binary tree (but not of types 1 or 2); and 0 for a binary tree of other types. Then in the second line, output the postorder traversal sequence of the tree. All the numbers in a line are separated by 1 space, and there must be no extra space at the beginning or the end of the line.
Sample Input 1:
7
4 2 5 1 6 3 7
1 2 4 5 3 6 7
Sample Output 1:
1
4 5 2 6 7 3 1
Sample Input 2:
10
8 4 9 2 10 5 1 6 3 7
1 2 4 8 9 5 10 3 6 7
Sample Output 2:
2
8 9 4 10 5 2 6 7 3 1
Sample Input 3:
10
8 4 2 5 11 1 6 3 14 7
1 2 4 8 5 11 3 6 7 14
Sample Output 3:
3
8 4 11 5 2 6 14 7 3 1
Sample Input 4:
7
4 2 10 5 1 3 7
1 2 4 5 10 3 7
Sample Output 4:
0
4 10 5 2 7 3 1
#include
#include
#include
#include
#include
#include
using namespace std;
struct node{
int data;
node* lchild;
node* rchild;
int height;
};
const int maxn=2100;
int pre[maxn];
int in[maxn];
node* newnode(int data){
node* root=new node;
root->data=data;
root->lchild=NULL;
root->rchild=NULL;
root->height=1;
return root;
}
node* create(int prel,int prer,int inl,int inr){
if(prel>prer) return NULL;
int mid=pre[prel];
node* root=newnode(mid);
int index;
for(int i=inl;i<=inr;i++){
if(in[i]==mid){
index=i;
break;
}
}
int leftnum=index-inl;
root->lchild=create(prel+1,prel+leftnum,inl,index-1);
root->rchild=create(prel+1+leftnum,prer,index+1,inr);
return root;
}
int deep;
void bfs(node* root){
queue<node*> q;
q.push(root);
while(!q.empty()){
node* now=q.front();
q.pop();
if(now->lchild!=NULL){
now->lchild->height=now->height+1;
deep=now->height+1;
q.push(now->lchild);
}
if(now->rchild!=NULL){
now->rchild->height=now->height+1;
deep=now->height+1;
q.push(now->rchild);
}
}
}
bool bfs1(node* root){
queue<node*> q;
q.push(root);
int tag=-1;
while(!q.empty()){
node* now=q.front();
q.pop();
if(now->lchild!=NULL&&now->rchild==NULL){
return false;
}
else if(now->lchild==NULL&&now->rchild!=NULL){
return false;
}
else if(now->lchild==NULL&&now->rchild==NULL){
if(tag!=-1&&now->height!=tag){
return false;
}
tag=now->height;
}
else{
if(tag!=-1) return false;
q.push(now->lchild);
q.push(now->rchild);
}
}
return true;
}
bool bfs2(node* root){
queue<node*> q;
q.push(root);
bool flag=true;
int tag=0;
while(!q.empty()){
node* now=q.front();
q.pop();
if(now->lchild!=NULL&&now->rchild==NULL){
if(tag==1) return false;
tag=1;
q.push(now->lchild);
}
else if(now->lchild==NULL&&now->rchild!=NULL){
return false;
}
else if(now->lchild==NULL&&now->rchild==NULL){
tag=1;
}
else{
if(tag==1) return false;
q.push(now->lchild);
q.push(now->rchild);
}
}
return flag;
}
bool bfs3(node* root){
queue<node*> q;
q.push(root);
while(!q.empty()){
node* now=q.front();
q.pop();
if(now->lchild!=NULL&&now->rchild==NULL&&now->height<deep-1){
return false;
}
else if(now->lchild==NULL&&now->rchild!=NULL&&now->height<deep-1){
return false;
}
else if(now->lchild==NULL&&now->rchild==NULL&&now->height<deep-1){
return false;
}
if(now->lchild!=NULL){
q.push(now->lchild);
}
if(now->rchild!=NULL){
q.push(now->rchild);
}
}
return true;
}
vector<int> v;
void dfs(node* root){
if(root==NULL) return;
dfs(root->lchild);
dfs(root->rchild);
v.push_back(root->data);
}
void print(){
for(int i=0;i<v.size();i++){
printf("%d",v[i]);
if(i!=v.size()-1) printf(" ");
else printf("\n");
}
}
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&in[i]);
}
for(int i=0;i<n;i++){
scanf("%d",&pre[i]);
}
node* root=create(0,n-1,0,n-1);
bfs(root);
if(bfs1(root)){
printf("1\n");
}
else if(bfs2(root)){
printf("2\n");
}
else if(bfs3(root)){
printf("3\n");
}
else printf("0\n");
dfs(root);
print();
}
这道题其实是一个模板题!需要记住判断满二叉树和完全二叉树的方法如何写!这个很关键!我写的方法我个人觉得看了很多方法是比较好理解的!
就是要记住,满二叉树的判断中:1.如果左右子树存在一个空一个不为空,则不是 2.如果都为空,则需要记住第一个没有孩子的节点高度,如果后序节点的高度不等于这个高度,那么也不是
完全二叉树就是:1.如果节点有右孩子没有左孩子,不是2.如果节点首次有左孩子没有右孩子,或者节点首次没有孩子,则tag置为1 3.如果节点tag为1,并且又有孩子了(可以插入),那么也不是
具体细节可以看我代码,比较简略且思路清晰。