qsort 对 int 型的排序~~~
注意调用 和自定义compare
#include<stdio.h>
#include<stdlib.h> // 调用的库函数
int compare(const void *a,const void *b); //函数的定义:定义一个比较函数~~ 这是判断函数排序的方法
int main()
{
int i;
int a[10]={1,2,3,2,4,5,2,1,3,0};
qsort(a,10,sizeof(a[1]),compare);
for(i=0;i<=9;i++)
printf("%d ",a[i]); // 排序好后 关键是在于输出 可以从头输出 从尾输出
system("pause");
}
int compare(const void *a,const void *b)
{
return *(int *)a-*(int *)b; //这是有小到大的输出
}
// return *(int *)b-*(int *)a; 这是由大到小的输出
输出的结果是:0 1 1 2 2 2 3 3 4 5
qsort 的函数原型是void __cdecl qsort ( void *base, size_t num, size_t width, int (__cdecl *comp)(const void *, const void* ) )
其中base是排序的一个集合数组,num是这个数组元素的个数,width是一个元素的大小,comp是一个比较函数。
比如:对一个长为1000的数组进行排序时,int a[1000]; 那么base应为a,num应为 1000,width应为 sizeof(int),comp函数随自己的命名。
qsort(a,1000,sizeof(int ),comp);
其中comp函数应写为:
int comp(const void *a,const void *b)
{
return *(int *)a-*(int *)b;
}
下面这是对float的 qsort的排序~~
#include<stdio.h>
#include<stdlib.h>
int compare(const void *a,const void *b);
int main()
{
int i,j;
float a[10]={1.1,2.1,3.2,1.4,2.9,4.2,5.3,2.2,1.7,3.2};
qsort(a,10,sizeof(a[1]),compare);
for(i=0;i<=9;i++)
{
printf("%f ",a[i]);
}
printf("\n");
system("pause");
}
int compare(const void *a,const void *b)
{
return (*(float*)a-*(float*)b>0?1:-1); //这是将浮点型转化为整形。
}
// char 型的函数 排序
#include<stdio.h>
#include<stdlib.h> // 调用的库函数 qsort
#include<string.h> // 调用的库函数 strcmp
int compare(const void *a,const void *b); //函数的定义:定义一个比较函数~~ 这是判断函数排序的方法
int main()
{
int i,j;
char a[10]={'m','n','s','a','q','f','g','h','i','j'};
qsort(a,10,sizeof(a[1]),compare);
for(i=0;i<=9;i++)
{
printf("%c ",a[i]); // 排序好后 关键是在于输出 可以从头输出 从尾输出
}
printf("\n");
system("pause");
}
int compare(const void *a,const void *b)
{ return strcmp((char*)a,(char*)b); }
小常识: 关于long long 和__int64 位的用法
现在数一下long long 和__int64位的用法, 在gnu c中应采用的是__int64位进行编辑 输入输出使用%I64d。在gnu c++中应当采用的是 long long 进行的编辑,输入输出是用%lld。
Int 的范围时2^31 约是20亿 unsigned int 是用的是40亿
Long long 和 __int64 的范围是
-9223372036854775808~9223372036854775807 总共有19位
关于一些 基本的math函数 和 float double 的范围 问题
经常采用的float 和double 的范围如下
float的范围为-2^128 ~ +2^128,精度为6~7位有效数字
double的范围为-2^1024 ~ +2^1024,精度为15~16位。
还有在 vitual judge 中 可以用 long long 来定义长整形 用%I64 进行输出结果;
下面附几个基本函数知识(浮点数转化为整型)
浮点型 天花板函数 ceil ,即求超过它的最小整数
地板函数 floor 即求不超过它的最大整数
整型 四舍五入 int(x+0.5)
下取整 应该直接来 int(x)就可以了吧~~
PI=2*acos(0.0)
double 要取大数的话 可以定义为2e100;
int 要取大数的话 可以定义为20亿;
eps 小量 定义为 1e-7
计算几何
求 多边形面积 只能是顺时针 或者逆时针的坐标
A – 多边形面积
Time Limit: 1000MS
Description
给出一个多边形的顶点坐标,请计算出这个多边形的面积 (不一定是凸多边形) 。
Input
输入的第一行为一个正整数t ( t<=10 ),表示有t组数据,对于每组数据:
第一行为一个正整数n ( 3<=n<=10 ),代表这个多边形的顶点数;紧跟n行,每行两个正整数x,y ( -100=<x,y<=100 )表示每个顶点的坐标;输入数据给的顶点顺序同时钟方向。
Output
每组数据输出一行,为一个保留一位小数的实数,即当前多边形的面积。
Sample Input
2
4
0 0
0 1
1 1
1 0
3
-2 3
3 2
1 -5
Sample Output
1.0
18.5
#include<iostream>
using namespace std;
struct node
{
int x,y;
}point[100];
int t,n,i,ans;
int main()
{
scanf("%d",&t);
while (t--)
{
scanf("%d",&n);
for (i=1;i<=n;i++) scanf("%d%d",&point[i].x,&point[i].y);
ans=0;
for (i=3;i<=n;i++)
{
ans+=(point[i].x-point[1].x)*(point[i-1].y-point[1].y)-
(point[i-1].x-point[1].x)*(point[i].y-point[1].y);
}
if (ans<0) ans=-ans;
printf("%.1lf\n",ans*0.5);
}
return 0;
}
Area of polygon
The area of a polygon with vertices (x 1, y 1), ..., (x n, y n) is equal to the determinant:
1 | x1 x2 ... xn |
--- | |
2 | y1 y2 ... yn |
where the determinate is defined to be similar to the 2 by 2 determinant: x1 y2 + x2y3+ ... + xn y1 - y1 x2 - y2x3 - ... - yn x1
判断是否为凸包 选用~~
创业是需要地盘的,HDU向钱江肉丝高新技术开发区申请一块用地,很快得到了批复,据说这是因为他们公司研发的“海东牌”老鼠药科技含量很高,预期将占全球一半以上的市场。政府划拨的这块用地是一个多边形,为了描述它,我们用逆时针方向的顶点序列来表示,我们很想了解这块地的基本情况,现在请你编程判断HDU的用地是凸多边形还是凹多边形呢?
Input
输入包含多组测试数据,每组数据占2行,首先一行是一个整数n,表示多边形顶点的个数,然后一行是2×n个整数,表示逆时针顺序的n个顶点的坐标(xi,yi),n为0的时候结束输入。
Output
对于每个测试实例,如果地块的形状为凸多边形,请输出“convex”,否则输出”concave”,每个实例的输出占一行。
Sample Input
4
0 0 1 0 1 1 0 1
0
Sample Output
convex
过多边形任意一边做一条直线,如果其他各顶点都在这条直线的同侧,则把这个多边形叫做凸多边形
我采用的是
(1)输入数据
(2)以相邻两点作为直线进行判断存在三种情况(我是利用高中的两点式求直线方程的~~)
1平行x轴直线
2平行y轴直线
3既不平行x轴也不平行y轴
(3)判断除了做这两条直线上的点,其他的点都是否在这条直线上的一边。
判断是否满足条件~~~
贴上代码~~
#include<stdio.h>
struct stu{
float x,y;
} point[1000000];
int n,sum1,sum2,sum,flag2,flag1,flag; //flag 是用来判断 特殊情况 平行x轴,y轴。
int judge(void);
int judgex(int i); //判断平行x轴情况
int judgey(int i); //判断平行y轴情况
int main()
{
int i,t,result;
while(scanf("%d",&n)&&n!=0){
//输入数据
for(i=1;i<=n;i++)
scanf("%f %f",&point[i].x,&point[i].y);
point[i].x=point[1].x;
point[i].y=point[1].y;
sum1=sum2=sum=0;
result=judge();
if(result==1)printf("convex\n"); //根据judge的返回值来判断是否是凸包
else printf("concave\n");
}
}
int judge(void)
{
int recycle,i,j;
float a,b;
recycle=n;
for(j=1;j<=recycle;j++){ //判断所有点是否在一条直线的同侧
flag1=flag2=flag=0;
if(point[j].x-point[j+1].x==0){judgey(j);if(flag==1)sum++;/*printf("sum=%d\n",sum);*/continue; }
if(point[j].y-point[j+1].y==0){judgex(j);if(flag==1)sum++;/*printf("sum=%d\n",sum);*/ continue; }
a=(point[j].y-point[j+1].y)/(point[j].x-point[j+1].x);
b=point[j].y-a*point[j].x;
//printf("a=%f b=%f\n",a,b); //
sum1=sum2=0;
for(i=1;i<=recycle;i++)
{ if(i==j||i==j+1)
{
sum1++;sum2++; //printf("sum1=%d sum2=%d\n",sum1,sum2); //
continue;
}
if(a*point[i].x-point[i].y+b>=0) sum1++;
if(a*point[i].x-point[i].y+b<=0) sum2++;
//printf("sum1=%d sum2=%d\n",sum1,sum2); //
}
if(sum1==n||sum2==n) sum++;
// printf("sum=%d\n",sum);
}
// printf("sum=%d\n",sum); //
if(sum==n)return 1;
else return 0;
}
int judgex(int i)
{
int j;
for(j=1;j<=n;j++)
{
if(point[i].y>=point[j].y)flag1++;
if(point[i].y<=point[j].y)flag2++;
}
if(flag1==n||flag2==n)flag=1;
}
int judgey(int i)
{
int j;
for(j=1;j<=n;j++)
{
if(point[i].x>=point[j].x)flag1++;
if(point[i].x<=point[j].x)flag2++;
}
if(flag1==n||flag2==n)flag=1;
}
字典树 的构造 注意释放构造空间
Given a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of another. Let’s say the phone catalogue listed these numbers:
1. Emergency 911
2. Alice 97 625 999
3. Bob 91 12 54 26
In this case, it’s not possible to call Bob, because the central would direct your call to the emergency line as soon as you had dialled the first three digits of Bob’s phone number. So this list would not be consistent.
Input
The first line of input gives a single integer, 1 <= t <= 40, the number of test cases. Each test case starts with n, the number of phone numbers, on a separate line, 1 <= n <= 10000. Then follows n lines with one unique phone number on each line. A phone number is a sequence of at most ten digits.
Output
For each test case, output “YES” if the list is consistent, or “NO” otherwise.
Sample Input
2
3
911
97625999
91125426
5
113
12340
123440
12345
98346
Sample Output
NO
YES
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void maketire(char temp1[]);
int search(char temp2[]);
structnode{
structnode *next[27];
int count;
}*root;
int freedom(structnode *p);
int main()
{ char temp[10020][12];
int sum=0,i,n,m,len,judge;
scanf("%d",&n);
while(n--){
root=(structnode*)malloc(sizeof(structnode));
for( i=0;i<10;i++)
root->next[i]=NULL;
root->count=0;
scanf("%d",&len);
for(i=0;i<len;i++)
{
scanf("%s",temp[i]);
maketire(temp[i]);
}
judge=0;
for( i=0;i<len;i++){
judge=search(temp[i]);
if(judge==1)break;
}
if(judge==1)printf("NO\n");
else printf("YES\n");
freedom(root);
}
return 0;
}
void maketire(char temp1[]) {
structnode *r,*tem;
int len,i,j;
r=root;
len=strlen(temp1);
for(i=0;i<len;i++){
if(r->next[temp1[i]-'0']==NULL){
tem=(structnode*)malloc(sizeof(structnode));
for(j=0;j<10;j++)
tem->next[j]=NULL;
tem->count=0;
r->next[temp1[i]-'0']=tem;
}
r=r->next[temp1[i]-'0'];
r->count++;
}
}
int search(char temp2[]){
structnode *r;
int len,i;
r=root;
len=strlen(temp2);
for(i=0;i<len;i++){
if(r->next[temp2[i]-'0']!=NULL){
r=r->next[temp2[i]-'0'];
if((i==len-1)&&(r->count>1))return 1;
if(r->count==1)break;
}
}
return 0;
}
int freedom(structnode *p){ /* 这里就是树空间的释放代码~~重要~~ */
int i=0;
for(i=0;i<10;i++)
if(p->next[i]!=NULL) freedom(p->next[i]);
free(p);
}
A prefix of a string is a substring starting at the beginning of the given string. The prefixes of "carbon" are: "c", "ca", "car", "carb", "carbo", and "carbon". Note that the empty string is not considered a prefix in this problem, but every non-empty string is considered to be a prefix of itself. In everyday language, we tend to abbreviate words by prefixes. For example, "carbohydrate" is commonly abbreviated by "carb". In this problem, given a set of words, you will find for each word the shortest prefix that uniquely identifies the word it represents.
In the sample input below, "carbohydrate" can be abbreviated to "carboh", but it cannot be abbreviated to "carbo" (or anything shorter) because there are other words in the list that begin with "carbo".
An exact match will override a prefix match. For example, the prefix "car" matches the given word "car" exactly. Therefore, it is understood without ambiguity that "car" is an abbreviation for "car" , not for "carriage" or any of the other words in the list that begins with "car".
Input
The input contains at least two, but no more than 1000 lines. Each line contains one word consisting of 1 to 20 lower case letters.
Output
The output contains the same number of lines as the input. Each line of the output contains the word from the corresponding line of the input, followed by one blank space, and the shortest prefix that uniquely (without ambiguity) identifies this word.
Sample Input
carbohydrate
cart
carburetor
caramel
caribou
carbonic
cartilage
carbon
carriage
carton
car
carbonate
Sample Output
carbohydrate carboh
cart cart
carburetor carbu
caramel cara
caribou cari
carbonic carboni
cartilage carti
carbon carbon
carriage carr
carton carto
car car
carbonate carbona
答案代码:
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<stdlib.h>
void maketire(char temp1[]);
void search(char temp2[]);
struct node{
struct node *next[27];
int count;
}*root;
int main()
{ char temp[1000][22];
int sum=0,i;
root=(struct node*)malloc(sizeof(struct node));
for( i=0;i<26;i++)
root->next[i]=NULL;
root->count=0;
while(scanf("%s",temp[sum])!=EOF){
maketire(temp[sum]);
sum++;
}
for( i=0;i<sum;i++){
printf("%s ",temp[i]);
search(temp[i]);
printf("\n");
}
return 0;
}
void maketire(char temp1[]) {
struct node *r,*tem;
int len,i,j;
r=root;
len=strlen(temp1);
for(i=0;i<len;i++){
if(r->next[temp1[i]-'a']==NULL){
tem=(struct node*)malloc(sizeof(struct node));
for(j=0;j<26;j++)
tem->next[j]=NULL;
tem->count=0;
r->next[temp1[i]-'a']=tem;
}
r=r->next[temp1[i]-'a'];
r->count++;
}
}
void search(char temp2[]){
struct node *r;
int len,i;
r=root;
len=strlen(temp2);
for(i=0;i<len;i++){
if(r->next[temp2[i]-'a']!=NULL){
printf("%c",temp2[i]);
r=r->next[temp2[i]-'a'];
if(r->count==1)break;
}
}
}
数论
欧几里德:
//GCD不存在(x,0)的情况
#include<stdio.h>
int GCD(int n,int m);
int main()
{
int a,b,divide;
while(scanf("%d %d",&a,&b)!=EOF)
{
divide=GCD(b,a%b);
printf("%d\n",divide);
}
}
int GCD(int n,int m)
{
if(m==0) return n;
else return GCD(m,n%m);
}
扩展欧几里德: 青蛙的约会 选用
#include<stdio.h>
int flag=0;
long long Euclid(long long a,long long b,long long &x,long long &y);
int main()
{
long long x,y,m,n,len,divide,X,Y,result,z;
while(scanf("%lld %lld %lld %lld %lld",&x,&y,&m,&n,&len)!=EOF)
{
divide=Euclid(n-m,len,X,Y);
if((x-y)%divide!=0)printf("Impossible\n");
else {
z=len/divide;
result=((x-y)/divide*X%z+z)%z;
printf("%lld\n",result);
}
}
}
long long Euclid(long long a,long long b,long long &x,long long &y)
{
int tx,divide;
if(b==0){
x=1;
y=0;
return a;
}
divide=Euclid(b,a%b,x,y);
tx=x;
x=y;
y=tx-a/b*x;
return divide;
}
筛选法求素数 二分查找
#include<stdio.h>
#include<string.h>
int binarysearch(int n,int begin,int end);
int a[1000010],b[500000];
int main()
{
int i,j,k=1,above,n,sum1,sum2,flag;
memset(a,0,sizeof(a));
for(i=2;i*i<1000000;i++)
{
if(a[i]==1)continue;
else{
j=i;
for(j=j+j;j<1000000;j+=i)
{
a[j]=1;
}
}
}
for(i=3;i<=1000000;i++)
{
if(a[i]==0){b[k]=i;k++;}
}
above=k-1;
while(scanf("%d",&n)&&n!=0)
{
flag=0;
for(i=1;i<=above/2+1;i++)
{
sum1=b[i];
sum2=n-b[i];
flag=binarysearch(sum2,1,above);
if(flag==1){printf("%d = %d + %d\n",n,sum1,sum2);break;}
}
if(flag==0)printf("Goldbach's conjecture is wrong.\n" );
}
return 0;
}
int binarysearch(int n,int begin,int end)
{
int middle;
middle=(begin+end)/2;
if(b[middle]==n)return 1;
if(end-begin==0)return 0;
if(b[middle]>n)return binarysearch(n,1,middle-1);
if(b[middle]<n)return binarysearch(n,1+middle,end);
}
因式分解
tn=n;
for(i=2;i*i<=n;i++)//试除2~sqrt(n)
if(tn%i==0){//如果能被i整除
p[++cnt]=i;//保存底数
e[cnt]=0;//保存指数
while(tn%i==0){//计算指数
e[cnt]++;
tn/=i;
} }}
if(tn>1){//存在大于sqrt(n)的素因子
p[++cnt]=tn;
e[cnt]=1;
}
可分割的0-1背包 用贪心
#include<stdio.h>
struct stu {
double j,f,ave;
}a[100005];
int main()
{
int m,n,i,j,ji;
float value,sum,max,temp;
while(scanf("%d %d",&m,&n)!=EOF&&(m!=-1&&n!=-1))
{
for(i=1;i<=n;i++)
{
scanf("%lf %lf",&a[i].j,&a[i].f);
a[i].ave=a[i].j/a[i].f;
}
for(i=1;i<=n-1;i++)
{
max=a[i].ave;ji=i;
for(j=i+1;j<=n;j++)
if(max<a[j].ave){max=a[j].ave;ji=j;}
temp=a[ji].ave;
a[ji].ave=a[i].ave;
a[i].ave=temp;
temp=a[ji].j;
a[ji].j=a[i].j;
a[i].j=temp;
temp=a[ji].f;
a[ji].f=a[i].f;
a[i].f=temp;
}
value=sum=0;
for(i=1;i<=n;i++)
{
sum+=a[i].f;value+=a[i].j;
if(sum==m)break;
if(sum>m){sum-=a[i].f;
value-=a[i].j;
value+=(m-sum)*a[i].ave;
break;}
}
printf("%.3lf\n",value);
}
}
KMP
剪花布条
Sample Input
abcde a3
aaaaaa aa
Sample Output
0
3
Code
#include<stdio.h>
#include<string.h>
void getnext();
char a[1100],b[1100];
int next[1100];
int len1,len2;
int main()
{
int i,j,sum;
while(scanf("%s",a))
{
len1=strlen(a);
if(len1==1&&a[0]=='#')break;
scanf("%s",b);
len2=strlen(b);
getnext();
i=j=sum=0;
while(i<len1)
{
if(j==-1||a[i]==b[j])
{
i++;
j++;
}
else j=next[j];
if(j>=len2){sum++;j=0;}
}
printf("%d\n",sum);
}
}
void getnext()
{
int j=0,k=-1;
next[0]=-1;
while(j<len1-1)
{
if(k==-1||b[j]==b[k])
{
j++;
k++;
next[j]=k;
}
else k=next[k];
}
}