Language: C++

#define _USE_MATH_DEFINES
#include <climits>
#include<cmath>

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<utility>
#include<vector>

class Points{
private:
    
	std::pair<int,int> nCood;
	double dArg;
    double dLength_2;
public:
	Points(){
		nCood.first = nCood.second = dArg = dLength_2 = 0;
	}
	inline void SetPoint (std::pair<int,int>& nInput){
	nCood=nInput;
  
	return;
	}
    std::pair<int,int>nnGetCood(){
	return nCood;
	}
	void SetArg (Points StartPoint ){
		
		double dLengthVector=std::sqrt((nCood.first-(StartPoint.nnGetCood()).first)*(nCood.first-(StartPoint.nnGetCood()).first)+(nCood.second-(StartPoint.nnGetCood()).second)*(nCood.second-(StartPoint.nnGetCood()).second)*1.);
		double dCos=(nCood.first-(StartPoint.nnGetCood()).first)/dLengthVector;
		dArg=std::acos(dCos);
		return;
	}
    void SetLength (Points StartPoint){
        dLength_2 = (nCood.first - StartPoint.nnGetCood().first)*(nCood.first - StartPoint.nnGetCood().first) 
                    + (nCood.second - StartPoint.nnGetCood().second)*(nCood.second - StartPoint.nnGetCood().second);
        return;
    }
	
	double dGetArg(){
	return dArg;
	}
    double dGetLength_2(){
	return dLength_2;
    }
    void PrintCood(){
    printf("%d %d\n",nCood.first,nCood.second);
    }
};

/*
*?????????????????????
*/
void quick_sort_part(std::vector<Points>&points,int left,int right);
int partition(std::vector<Points>&points,int left,int right);
/*
*????????§????????????????¶?
*/
void quick_sort_part_2(std::vector<Points>&points,int nUpDown ,int left,int right);
int partition_2(std::vector<Points>&points,int nUpDown,int left,int right);
/*
*??????dArg??????????????????????????????????????????????????????
*?????????points[0]??????????????¢??§?±??????????
*/
void judgeIsometric(std::vector<Points>&points);
/*
*??????????¬?????????£(true)??????????????§???i???????????¶?????????????????????????????????
*1<=i<=points.size()-2,i==points.size()-2
*/
bool bCrossProduct (Points &points, std::vector<std::pair<int,int> >
    & StackPoints,int i);

bool bIsPararell(std::vector<Points>&points,int nI,int nJ);
int main(void){
   
	int nInput;
    scanf("%d",&nInput );
	
	std::vector<Points> aComp_nPoints(nInput);
    std::pair<int,int> prnnInput;
	int nMinX = INT_MAX,nMinY = INT_MAX;
	int nIndexMin;
    
    for (int i = 0;i< nInput;++i){
    
        scanf_s("%d%d",&(prnnInput.first),&(prnnInput.second) );
		aComp_nPoints[i].SetPoint(prnnInput);
			
            if (nMinY == prnnInput.second && nMinX > prnnInput.first){
                nMinX = prnnInput.first;
                nIndexMin = i;
            }
            else if (nMinY > prnnInput.second){
				nMinY = prnnInput.second;
                nMinX = prnnInput.first;
                nIndexMin = i;
            
			}
            
	}
	/*
	*??¶??????????????§y???????°??????§????????????????????§?????????x????°???????????????¢???
	*/
	if (nIndexMin != 0){
	std::swap(aComp_nPoints[0],aComp_nPoints[nIndexMin]);
	}
	/*
	*aComp_nPoints[0]????????????????§?????±????????°?????????????aComp_nPoints[i>0]?????????????????????
	*/
	for(int i = 1;i < nInput;++i){
		aComp_nPoints[i].SetArg ( aComp_nPoints[0] );
	}
    quick_sort_part(aComp_nPoints,0,aComp_nPoints.size()-1);
	
    
    judgeIsometric (aComp_nPoints);


  
   
    std::vector<std::pair<int,int> > pnnPrintPoints(aComp_nPoints.size());
    pnnPrintPoints[0]=aComp_nPoints[0].nnGetCood();
    int iIndex=0;
    for (int i = 1; i <aComp_nPoints.size()-1 ; ++i){
        pnnPrintPoints[++iIndex]=aComp_nPoints[i].nnGetCood();

         while (!bCrossProduct (aComp_nPoints[i+1],pnnPrintPoints,iIndex)){
             --iIndex  ;
        }
       
    }
    pnnPrintPoints[++iIndex]=aComp_nPoints[aComp_nPoints.size()-1].nnGetCood();
    
     
    printf("%d\n",++iIndex);//++??¢???????????????=????´???°

    
    for (int i = 0 ;i < iIndex; ++i){
        printf("%d %d\n",pnnPrintPoints[i].first,pnnPrintPoints[i].second);
    }
   //system ("pause");
	return 0;
}

int partition (std::vector<Points>&points,int left,int right){
    
    double dValue = points[right].dGetArg();
    int iIndex = left-1;
    for (int j = left;j <= right-1;++j){
        if(points[j].dGetArg() <= dValue){
        ++iIndex;
        std::swap(points[iIndex],points[j]);
        }
    }
    std::swap(points[iIndex+1],points[right]);
        return iIndex+1;
}
void quick_sort_part (std::vector<Points>&points,int left,int right){
    if (left<right){
        int nMiddleIndex=partition(points, left, right);
        quick_sort_part ( points, left, nMiddleIndex-1);
        quick_sort_part ( points, nMiddleIndex+1, right);
    }

    return;   
}

int partition_2 (std::vector<Points>&points,int nUpDown,int left,int right){
    
    double dValue = points[right].dGetLength_2();
    int iIndex = left-1;
    for (int j = left;j <= right-1;++j){
        if(nUpDown==1&&points[j].dGetLength_2() <= dValue){
        ++iIndex;
        std::swap(points[iIndex],points[j]);
        }
        else  if(nUpDown==-1&&points[j].dGetLength_2() >= dValue){
        ++iIndex;
        std::swap(points[iIndex],points[j]);
        }
    }
    std::swap(points[iIndex+1],points[right]);
        return iIndex+1;
}
void quick_sort_part_2 (std::vector<Points>&points,int nUpDown,int left,int right){
    if (left < right){
        int nMiddleIndex = partition_2(points,nUpDown, left, right);
        quick_sort_part_2 ( points,nUpDown, left, nMiddleIndex - 1);
        quick_sort_part_2 ( points,nUpDown, nMiddleIndex + 1, right);
    }

    return;   
}

void judgeIsometric (std::vector<Points>&points){
    points[points.size() - 1].SetLength(points[0]);
    int iLeft=1,iRight=1;
    for (int i = 1 ; i < points.size() - 1 ; ++i){
        if (bIsPararell (points,i,i+1)){
            iRight=i+1;
            if(!points[i].dGetLength_2()){
                points[i].SetLength(points[0]);          
            }
            points[i+1].SetLength(points[0]);
               if (iRight==points.size() - 1){
                quick_sort_part_2 (points,-1,iLeft,iRight);
                }
            }
        else{
            if (iLeft!=iRight){
                if (iLeft==1){
                quick_sort_part_2 (points,1,iLeft,iRight);
                }
              
                else{
                quick_sort_part_2 (points,-1,iLeft,iRight);
                points.erase(points.begin() + iLeft + 1,points.begin() +iRight );
                }
            }
            iLeft = iRight =i+1;
        }
    }    
    return;
}
bool bIsPararell(std::vector<Points>&points,int nI,int nJ){
  int nPararellCriterion =   (points[nI].nnGetCood().first - points[0].nnGetCood().first) * (points[nJ].nnGetCood().second - points[0].nnGetCood().second)
                           -(points[nJ].nnGetCood().first - points[0].nnGetCood().first) * (points[nI].nnGetCood().second - points[0].nnGetCood().second);
  return nPararellCriterion ==0;
}
bool bCrossProduct (Points &points, std::vector<std::pair<int,int> >
    & StackPoints,int i){
       
  
    double dValueCrossPro;
    if ( 0 < i && i < StackPoints.size())
    {
        dValueCrossPro = 
            (StackPoints[i].first - StackPoints[i-1].first) 
                * (points.nnGetCood().second - StackPoints[i].second)
            -(StackPoints[i].second - StackPoints[i-1].second) 
                * (points.nnGetCood().first - StackPoints[i].first) ;
        return dValueCrossPro >= 0;
    }
    else {
        printf("errorCrossProduct\n");      
        return false;
        }
     
}

Compiler output:
a.cc: In function 'int main()':
a.cc:88:9: error: 'scanf_s' was not declared in this scope; did you mean 'scanf'?
   88 |         scanf_s("%d%d",&(prnnInput.first),&(prnnInput.second) );
      |         ^~~~~~~
      |         scanf