这个题,神神叨叨,结果却异常无聊。
使用凸包就解决了,但是输入的问题,又对java语言表示了歧视。
具体见代码,BufferedReader StringTokenize scanner都RE,参照最下面的输入类,可以AC
import java.io.*;
import java.util.*;
public class Main{
static Node1696 baseNode;
static Node1696[] nodes;
static boolean[] visited;
public static void main(String[] args) throws Exception{
//System.setIn(new FileInputStream("C:\\Users\\XAGDC\\Desktop\\1696.1"));
//BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
//StringTokenizer st=new StringTokenizer(reader.readLine());
//Scanner st=new Scanner(System.in);
sc.init(System.in);
int M=sc.nextInt();//测试用例的个数
for (int i = 0; i <M ; i++) {
//st=new StringTokenizer(reader.readLine());
int N=sc.nextInt();//植物的数量
if(N==1){
int index=sc.nextInt();
int x=sc.nextInt();
int y=sc.nextInt();
System.out.println("1 "+index);
continue;
}
nodes=new Node1696[N+1];
visited=new boolean[N+1];
for (Node1696 node:nodes) {
node=new Node1696();
}
int Min_y=2087654321;
for (int j = 1; j <=N ; j++) {
//st=new StringTokenizer(st.readLine());
int index=sc.nextInt();
int x=sc.nextInt();
int y=sc.nextInt();
if(y<Min_y){
Min_y=y;
}
nodes[j]=new Node1696(index,x,y);
}
nodes[0]=new Node1696(0,0,Min_y);
baseNode=nodes[0];
List<Integer> list=new ArrayList<Integer>();
while(list.size()<N+1){
//System.out.printf("当前list的size是 %d ,一共有 %d 个数据,数据还没有加完 \n",list.size(),N);
List<Integer> lt=TUBAO(nodes);
list.addAll(lt);
//list.addAll(lt.subList(0,lt.size()-2));
/*System.out.printf("新的一轮后 N是 %d ,list的size是 %d , (N+1-list.size():%d ) \n list里存放了 ",N,list.size(),(N+1-list.size()));
for (int j = 0; j <list.size() ; j++) {
System.out.printf(list.get(j)+" ");
}
System.out.println("");*/
Node1696 [] nodesNew=new Node1696[N+1-list.size()];
if(list.size()>=N+1){
break;
}
nodesNew[0]=baseNode;
int index=1;
for(Node1696 node:nodes){
if(!visited[node.index] && node.index!=baseNode.index){
nodesNew[index]=node;
index++;
}
}
nodes=nodesNew;
}
System.out.print(list.size()-1+" ");
for (int j = 1; j <list.size() ; j++) {//0放的是起点,不需要打印
System.out.printf(list.get(j)+" ");
}
System.out.println("");
}
//sc.close();
}
public static List<Integer> TUBAO(Node1696[] nodeArr){
/*System.out.printf("要开始执行TUBAO算法了,先把要处理的节点数据打印一下 \n");
System.out.printf("base节点信息是 %s 共有节点数 %d \n ",baseNode,nodeArr.length);
System.out.println(Arrays.toString(nodeArr));*/
List<Integer> list=new ArrayList<Integer>();
if(nodeArr.length<=2){
if(nodeArr.length==1){
list.add(nodeArr[0].index);
visited[nodeArr[0].index]=true;
}else{
list.add(nodeArr[0].index);
list.add(nodeArr[1].index);
visited[nodeArr[0].index]=true;
visited[nodeArr[1].index]=true;
}
return list;
}
//baseNode=nodeArr[0];//这是最左下侧的点,是一个极点
int N= nodeArr.length;
Arrays.sort(nodeArr,1,N,new Comparator<Node1696>(){//从baseP开始,将点按照夹角排序
@Override
public int compare(Node1696 o1, Node1696 o2) {
return CCW(baseNode,o1,o2) >0 ? -1:1;
}
});
//点在左侧(CCW<0),V++, 点在右侧,需要回溯V--
int V=1;
Node1696[] res=new Node1696[N+2];
res[0]=nodeArr[0];
res[1]=nodeArr[1];
visited[nodeArr[0].index]=true;
visited[nodeArr[1].index]=true;
/*System.out.printf(" 使用%d 节点为base进行排序 \n",baseNode.index);
System.out.println("排序之后是 "+Arrays.toString(nodeArr));*/
for (int i = 2; i <N ; i++) {
while(CCW(res[V-1] ,res[V] ,nodeArr[i]) <0){
V--;
}
res[++V]=nodeArr[i];
}
baseNode=res[V];
for (int i = 0; i <V ; i++) {
list.add(res[i].index);
visited[res[i].index]=true;
}
/*System.out.printf("TUBAO执行完了,把找出的点打印一下\n");
for (Integer i:list
) {
System.out.printf("%d ",i);
}
System.out.println("\n");*/
return list;
}
public static int CCW(Node1696 A,Node1696 B,Node1696 C){// >0 逆时针 <0 顺时针
return A.x*B.y+B.x*C.y+C.x*A.y-(A.y*B.x+B.y*C.x+C.y*A.x) >0?1:-1;
}
static class sc{
static BufferedReader reader;
static StringTokenizer tokenizer;
static void init(InputStream input){
reader=new BufferedReader(new InputStreamReader(input));
tokenizer=new StringTokenizer("");
}
static String next() throws IOException{
while(!tokenizer.hasMoreTokens()){
tokenizer=new StringTokenizer(reader.readLine());
}
return tokenizer.nextToken();
}
static int nextInt() throws IOException{
return Integer.parseInt(next());
}
}
}
class Node1696{
int index;
int x;
int y;
public Node1696() {
}
public Node1696(int index, int x, int y) {
this.index = index;
this.x = x;
this.y = y;
}
@Override
public String toString() {
return "Node1696{" +
"index=" + index +
", x=" + x +
", y=" + y +
'}'+"\n";
}
}