uva10716(贪心+c++ stl list的运用 java linkedlist的运用)
来源:互联网 发布:php 下载文件 编辑:程序博客网 时间:2024/06/13 14:21
本来是在做atcoder的题的,然后发现了这道几乎一样的题目。然而ac了这题,atcoder的papper sort却一直TLE。
思路:题目说的是给出一个字符串,问移动相邻的字符,最少需要多少次使其可以变成回文串。思路很简单,但是很多细节需要注意。先找与字符串最左边对应的,离最右边最近的字符,计算其移动到最优边所需移动的步数。然后删除二者,再在剩下的字符串中求解。由于删除如果用数组或者vector会很慢,做了一下优化改用双向链表。
开始不知道c++竟然有双项链表,用java打了一波,然而还是TLE,关键在atcoder的题上,用vector比用list还少tle一个答案,虽然其他数据List都要比vector版本来的快,不知道为什么,可能是写挫了,但是又不知道是什么数据,心情复杂。不过通过这个过程我又学了一下java的linkedlist和c++的list,也是挺好的。
c++:list的reverse_iterator运用参考此博文:https://www.cnblogs.com/SunboyL/p/reverse_iterator_erase.html
#include<iostream>#include<cstring>#include<string>#include<vector>#include<cstdio>#include<list>using namespace std;const int maxn=1e6+50;char s[maxn];bool judge;int length,cnte,cnto,cnt,temp,T,cnton,idx,t;int main(){ //freopen("out.txt", "w", stdout); while(scanf("%d",&t)!=EOF){ for(int i=0;i<t;i++){ scanf("%s",s); list<int> ss; list<int>::reverse_iterator rit; judge=true; length=strlen(s); cnt=cnte=cnto=cnton=0; for(int i=0;i<length;i++){ temp=s[i]-'a'; ss.push_back(temp); v[temp].push_back(i); } for(int i=0;i<26;i++){ if(!v[i].size()) continue; if(v[i].size()==length){///只有一个字母长度的时候 judge=false; break; } if(v[i].size()%2) cnto++;///奇数个数的字母 else cnte++;///出现偶数个数的字母 } if(length==1||!judge)///如果只有一个字母或全是相同的情况 printf("0\n"); else if((length%2&&cnte&&cnto<=1)||(!(length%2)&&!cnto)){///存在回文串 while(ss.size()){ judge=true; idx=ss.size()-1; for(rit=ss.rbegin();rit!=ss.rend()&&idx>0;rit++,idx--){///list的遍历 if(*rit==*ss.begin()){ cnt+=ss.size()-1-idx; list<int>::iterator it=ss.erase((++rit).base());///rit不能直接用erase方法,要先转化成it,这里具体参考上述博客 rit=list<int>::reverse_iterator(it); judge=false; break; } } ss.erase(ss.begin()); if(judge) cnt+=ss.size()/2;///如果是单独的一个,则需要把它移动到中间 } printf("%d\n",cnt); } else printf("Impossible\n"); } } return 0;}
java:
import java.util.LinkedList;import java.util.Scanner;class Main{static int T;public static void main(String[] args) {Scanner scan=new Scanner(System.in);while(scan.hasNextInt()){T=scan.nextInt();scan.nextLine();for(int k=0;k<T;k++){String s=new String();boolean judge;int length,cnt,cnte,cnto,temp,index;int[] kinds=new int[26];LinkedList<Integer> L=new LinkedList<Integer>();s=scan.nextLine();judge= true;length=s.length();cnt=cnte=cnto=0;for(int i=0;i<length;i++){temp=s.charAt(i)-'a';L.add(temp);kinds[temp]++;}for(int i=0;i<26;i++){if(kinds[i]==0)continue;if(kinds[i]==length){judge=false;break;}if(kinds[i]%2==1)cnto++;elsecnte++;}//System.out.println(cnte+" "+cnto+" "+L.get(0)+" "+L.size());if(length==1||!judge){System.out.println("0");}else if((length%2==1&&cnte!=0&&cnto<=1)||(length%2==0&&cnto==0)){while(L.size()!=0){judge=true;for(int j=L.size()-1;j>0;j--){if(L.get(j)==L.getFirst()){cnt+=L.size()-1-j;L.remove(j);judge=false;break;}}L.removeFirst();if(judge){cnt+=L.size()/2;}}System.out.println(cnt);}elseSystem.out.println("Impossible");}}}}
对比一下觉得java的api实现起来人性化很多。
阅读全文