a題 數字的序數。數字末帶“1”、“2”,“3”的一般加“st”、“nd”、“rd”但是以“11”、“12”、“13”結尾的加“th”,其他的都是加“th”。


#include <stdio.h>
int main()


{
int t,n;
scanf("%d",&t);
while (t--)

{
scanf("%d",&n);
if (n%10==1 && n%100!=11)
printf("%dst\n",n);
else if (n%10==2 && n%100!=12)
printf("%dnd\n",n);
else if (n%10==3 && n%100!=13)
printf("%drd\n",n);
else printf("%dth\n",n);
}
return 0;
}
b題,判斷各個函數的特殊情況。


#include <stdio.h>
int main()


{
double a,b,c,d,e,f;
int t;
scanf("%d",&t);
while (t--)

{
scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e,&f);
if (a==c)
printf("circle\n");
else if (a==0||c==0)
printf("parabola\n");
else if (a*c<0)
printf("hyperbola\n");
else
printf("ellipse\n");
}
return 0;
}
d題。模擬。zoj上不支持strrev。ce幾次。


#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define swap(x,y,z) ((z)=(x),(x)=(y),(y)=(z))
void move(char *s,int pos)


{
int i,len=strlen(s);
s[len+1]='\0';
for (i=len-1;i>=pos;i--)
s[i+1]=s[i];
}
int no_alnum(char *s)


{
int i;
for (i=0;i<strlen(s);i++)
if (isalnum(s[i]))
return 0;
return 1;
}
void deal(char *s)


{
int i,j,k,l,m,n,len=strlen(s),flag=1,f;
for (i=0;i<len;i++)

{
f=1;
if (isalnum(s[i]))

{
if (s[i]=='Z'||s[i]=='z'||s[i]=='9')

{

if (s[i]=='Z')
{s[i]='A'; }

if (s[i]=='z')
{s[i]='a'; }

if (s[i]=='9')
{s[i]='0'; }

if (no_alnum(s+i+1)&&isupper(s[i]))
{move(s,i+1);s[i+1]='A';f=0;}

if (no_alnum(s+i+1)&&islower(s[i]))
{move(s,i+1);s[i+1]='a';f=0;}

if (no_alnum(s+i+1)&&isdigit(s[i]))
{move(s,i+1);s[i+1]='1';f=0;}
if (f) deal(s+i+1);
}
else s[i]++;
flag=0;
break;
}
}
if (flag) s[0]++;
}
int main()


{
int t;
char s[110],tmp;
int c,i,len;
scanf("%d",&t);
while (t--)

{
scanf("%s%d",s,&c);
while (c--)

{
len=strlen(s);
for (i=0;i<len/2;i++)
swap(s[i],s[len-i-1],tmp);
//strrev(s);
deal(s);
len=strlen(s);
//strrev(s);
for (i=0;i<len/2;i++)
swap(s[i],s[len-i-1],tmp);
printf("%s\n",s);
}
printf("\n");
}
return 0;
}
F題。把數列排成一個圓,求對面那個數。


#include <stdio.h>
#include <string.h>
char s[105][25];
int main()


{
int t,i,n,k;
char fin[25];
scanf("%d",&t);
while (t--)

{
scanf("%d%s",&n,fin);
for (i=0;i<n;i++)

{
scanf("%s",s[i]);
if (strcmp(s[i],fin)==0)
k=i;
}
printf("%s\n",s[(k+n/2)%n]);
}
return 0;
}
L題。數學題。
紙老虎題,有n個盒子,第i個盒子里有i個東西,每次選取一些盒子,然后從這些盒子中每個都取出相同數目的東西。問至少幾次可以把盒子清空?
把每個盒子看成集合。有n個集合,分別有1…n個元素。具體每種集合有多少個是沒意義的,因為我們可以把具有相同元素的集合同時操作,所以我們可以用集合的種類代替集合的個數。假設,每次選取k個集合。從這k個集合里拿東西,則這k個集合拿過之后還是k個不同的集合(有可能有一個成空集),所以至少還有(k-1)個不同的集合,而除這k個外還有(n-k)個不同的集合。所以拿完之后不同集合的個數至少變為了r=max(k-1,n-k)。考慮當n是偶數時當k=n/2時,r取最小值,max(k-1,n-k)=n/2,當n為奇數時,k=(n+1)/2時,r取最小值max(k-1,n-k)=(n-1)/2。這個最小值是剩余集合數的一個下界。
其實這個下界是可以達到的:
n是偶數時,從元素個數不少于n/2的全部集合里都拿n/2個,則,剩余集合元素個數變為了1,2……n/2,問題規模縮小了一半。
n是奇數時,從元素個數不少于(n+1)/2的集合里都拿(n+1)/2個,則剩余集合元素個數變為了1,2,…(n-1)/2,問題規模也縮小了一半。
而在c語言中,除以2是下取整的,所以無論n為奇數還是偶數,一次操作之后集合個數至少變成了n/2,并且有辦法可以達到這個最小值。
于是,最少拿的次數就是每次把n不斷除以2,除到0為止。即n的2進制表示中的bit數。


#include <stdio.h>
typedef unsigned int uint;
uint a[33];
int main()


{
int t;
uint i,n;
a[0]=1;a[1]=2;
for (i=2;i<33;i++)
a[i]=2*a[i-1];
scanf("%d",&t);
while (t--)

{
scanf("%u",&n);
for (i=1;i<33;i++)
if (n>=a[i-1]&&n<a[i])

{printf("%u\n",i);break;}
}
return 0;
}
M題。求中值。


#include <stdio.h>
#include <stdlib.h>
int cmp(const void *a,const void *b)


{
return (*(double *)a)>(*(double *)b)?1:0;
}
double a[1000];
int main()


{
int t,i,n;
scanf("%d",&t);
while (t--)

{
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%lf",&a[i]);
qsort(a+1,n,sizeof(a[0]),cmp);
if (n%2) printf("%.3lf\n",a[n/2+1]);
else printf("%.3lf\n",(a[n/2]+a[n/2+1])/2.0);
}
return 0;
}