1012 Loop
题意:给一个长度为n的数字串可以进行k次操作,每次操作选择两个数交换位置,输出字典序最大的结果。
思路:
使用链表储存数串,从前往后遍历,如果遇到一个数字,满足将其删除可以增大字典序,即该数字小于下一个数字,则将其删除并保存到一个数组a中。将第i个数字删除后,回到第i-1个位置,这样就不会因为出现类似 4 3 5这样的删除之后为4 5(应为5).
然后将链表中的数串输出,最后将数组a排序后输出。
AC代码:
#include <stdio.h>
#include <stdlib.h>
struct Node{
int value;
Node* pre;
Node* next;
};
Node* createNode();
Node* deleteNode(Node* a);
int cmp(const void* a,const void* b);
Node* head=createNode();
int main()
{
int t;
int n,k;
scanf("%d",&t);
for(int i=0;i<t;i++){
scanf("%d %d",&n,&k);
Node* p=head;
for(int j=0;j<n;j++){
Node* node=createNode();
p->next=node;
node->pre=p;
p=node;
scanf("%d",&node->value);
}
int a[k]={0};
int m=0;
int max=0;
p=head->next;
while(p->next){
if(p->value<p->next->value){
a[m]=p->value;
m++;
p=deleteNode(p);
}
else p=p->next;
if(m==k) break;
}
max=m;
qsort(a,k,sizeof(int),cmp);
p=head->next;
m=0;
int sum=0;
while(p->next){
printf("%d",p->value);
sum++;
if(sum<n) printf(" ");
while(a[m]>p->next->value){
printf("%d",a[m]);
sum++;
if(sum<n) printf(" ");
m++;
}
p=p->next;
}
printf("%d",p->value);
sum++;
if(sum<n) printf(" ");
while(m<max){
printf("%d",a[m]);
sum++;
if(sum<n) printf(" ");
m++;
}
putchar('\n');
}
}
Node* createNode(){
Node* a;
a=(Node*)malloc(sizeof(Node));
a->next=NULL;
a->pre=NULL;
return a;
}
Node* deleteNode(Node* a){
if(a->pre==head){
a=a->next;
free(a->pre);
head->next=a;
a->pre=head;
return a;
}
else{
Node* q=a->pre;
a->pre->next=a->next;
a->next->pre=a->pre;
free(a);
return q;
}
}
int cmp(const void* a,const void* b){
return *(int*)b-*(int*)a;
}