6 pros of the 8th zjcpc

6 pros of the 8th zjcpc

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为止。即n2进制表示中的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;
}

你可能感兴趣的:(6 pros of the 8th zjcpc)