1008 数组元素循环右移问题

一个数组AAA中存有NNN>0>0>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移MMM≥0\ge 00)个位置,即将AAA中的数据由(A0A1⋯AN−1A_0 A_1 \cdots A_{N-1}A0A1AN1)变换为(AN−M⋯AN−1A0A1⋯AN−M−1A_{N-M} \cdots A_{N-1} A_0 A_1 \cdots A_{N-M-1}ANMAN1A0A1ANM1)(最后MMM个数循环移至最前面的MMM个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?

输入格式:

每个输入包含一个测试用例,第1行输入NNN1≤N≤1001\le N \le 1001N100)和MMM≥0\ge 00);第2行输入NNN个整数,之间用空格分隔。

输出格式:

在一行中输出循环右移MMM位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。

输入样例:

6 2
1 2 3 4 5 6

输出样例:

5 6 1 2 3 4
#include<stdio.h>
int main()
{
	int n,m;
	int i,j,a[100];
	
	scanf("%d %d",&n,&m);
	
	if(m>n)
	m=m%n;
	for(i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}
	
	for(i=n-m;i<n;i++)
	{
		printf("%d ",a[i]);
	}
	for(j=0;j<=n-m-2;j++)
	{
		printf("%d ",a[j]);
	}
	printf("%d",a[n-m-1]);
} 

 

输出月份英文名

本题要求实现函数,可以返回一个给定月份的英文名称。

函数接口定义:

char *getmonth( int n );

函数getmonth应返回存储了n对应的月份英文名称的字符串头指针。如果传入的参数n不是一个代表月份的数字,则返回空指针NULL。

裁判测试程序样例:

#include <stdio.h>

char *getmonth( int n );

int main()
{
    int n;
    char *s;

    scanf("%d", &n);
    s = getmonth(n);
    if ( s==NULL ) printf("wrong input!\n");
    else printf("%s\n", s);

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例1:

5

输出样例1:

May

输入样例2:

15

输出样例2:

wrong input!
char *getmonth( int n )
{
    switch(n)
    {
    case 1:return "January";
    case 2:return "February";
    case 3:return "March";
    case 4:return "April";
    case 5:return "May";
    case 6:return "June";
    case 7:return "July";
    case 8:return "August";
    case 9:return "September";
    case 10:return "October";
    case 11:return "November";
    case 12:return "December";
    default:return NULL;
    }
}

 

浙大版《C语言程序设计(第3版)》题目集

习题10-4 递归求简单交错幂级数的部分和 (15 分)

本题要求实现一个函数,计算下列简单交错幂级数的部分和:

f(x,n)=xx2+x3x4++(1)n1xn

函数接口定义:

double fn( double x, int n );

其中题目保证传入的n是正整数,并且输入输出都在双精度范围内。函数fn应返回上述级数的部分和。建议尝试用递归实现。

裁判测试程序样例:

#include <stdio.h>

double fn( double x, int n );

int main()
{
    double x;
    int n;

    scanf("%lf %d", &x, &n);
    printf("%.2f\n", fn(x,n));

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

0.5 12

输出样例:

0.33
double fn( double x, int n )
{	
	if(n==1)
		return x;
	else
		return x-x*fn(x,n-1);
}

 

1007 素数对猜想

1007 素数对猜想 (20 分)

让我们定义dn为:dn=pn+1pn,其中pi是第i个素数。显然有d1=1,且对于n>1dn是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。

现给定任意正整数N(<105),请计算不超过N的满足猜想的素数对的个数。

输入格式:

输入在一行给出正整数N

输出格式:

在一行中输出不超过N的满足猜想的素数对的个数。

输入样例:

20

输出样例:

4
#include<stdio.h>
#include<math.h>
int fac(int n)//判断是否为素数
{
	int i;
	
	if(n==1)
		return 0;
	if(n==2)
		return 1;
	if(n%2==0)
		return 0;
	for(i=2;i<=sqrt(n)+1;i++)
	{
		if(n%i==0)
		return 0;
	} 
	return 1;
}
int main()
{
	int n,i;
	int num=0;
	
	scanf("%d",&n);
	for(i=3;i<=n;i++)
		if(fac(i))
			if(fac(i+2)&&i+2<=n)
				num++;
	printf("%d",num);
}

 

结构指针

结构指针的概念

结构指针就是指向结构变量的指针

例:

struct student s1={10,"wang",8,7,9},*p;

p=&s1;

第一条语句定义了struct student 类型的变量s1并初始化,另外还定义了一个结构指针变量

第二条语句使结构指针指向结构变量s1,结构指针的值实际上是结构变量的首地址

用*p访问结构成员
(*p).num=10;

(*p)的括号是不可少的,因为成员运算符“.”的优先级高于“*”的优先级。

用指向运算符->访问指针指向的结构成员
p->num=10;

在使用结构指针访问结构成员时,通常使用指向运算符->

结构指针作为函数参数

int score (struct student *p,int n,int num,int course,int score);

其调用语句

pos=score(students,n,num,course,score);

对应的实参是结构数组名students

PAT (Basic Level) Practice (中文)1003 我要通过!

1003 我要通过! (20 分)

答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。

得到“答案正确”的条件是:

  1. 字符串中必须仅有 PAT这三种字符,不可以包含其它字符;
  2. 任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
  3. 如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 abc 均或者是空字符串,或者是仅由字母 A 组成的字符串。

现在就请你为 PAT 写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。

输入格式:

每个测试输入包含 1 个测试用例。第 1 行给出一个正整数 n (<10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过 100,且不包含空格。

输出格式:

每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出 YES,否则输出 NO

输入样例:

8
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA

输出样例:

YES
YES
YES
YES
NO
NO
NO
NO
#include<stdio.h>
#include<string.h>
int main()
{
	int n,i;
	char s1[100];
	int count=0,j=0,k=0,num1,num2,num3,num;
	int a[20]={0}; 
	
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		count=0;num1=0;num2=0;num3=0;num=0; 
		scanf("%s",&s1); 
		for(j=0;j<=strlen(s1);j++)
		{
			if(s1[j]=='A'||s1[j]=='P'||s1[j]=='T')
			{
				count++;	
			}
		}
		for(j=0;j<=strlen(s1);j++)
		{
			if(s1[j]=='A')
			{
				num++;	
			}
		}
		j=0;
		while(s1[j++]!='P')
		{
			num1++;	
		}
		while(s1[j++]!='T')
		{
			num2++;
		}
		num3=strlen(s1)-num1-num2-2;
		if(count==strlen(s1)&&count>=3)
		{
			if(num3==num1*num2)
				a[k++]=1;
			else if(s1[0]=='P'&&s1[strlen(s1)-1]=='T'&&num==count-2)
				a[k++]=1;
			else
				a[k++]=0;
		}
		else
			a[k++]=0;
	}
	for(i=0;i<k;i++)
	{
		if(a[i]==1)
		printf("YES\n");
		else
		printf("NO\n");	
	}
}

个人认为这道题最难的就是对题目的理解,以下是我个人对于题目的分析:

如果 aPbTc 正确,则 aPbATca 正确

如果PAT(a=NULL,b=A,c=NULL)正确,则PAAT,PAAAT,PAAAAT等都正确。

如果APATA(a=A,b=A,c=A)正确,则APAATAA,APAAATAAA,APAAAATAAAA等都正确。

如果PATA(a=NULL,b=A,c=A)正确,则PAATA,PAAATA,PAAAATA等都正确。//这种情况不可能发生,因为“任意形如 xPATx 的字符串都可以获得’答案正确‘”。

如果APAT(a=A,b=A,c=NULL)正确,则APAATA,APAAATAA,APAAAATAAA等都是正确的。//这种情况不可能发生,因为”任意形如 xPATx 的字符串都可以获得’答案正确’

指针,数组和地址间的关系

联系:数组名本身是一个地址即指针值

区别:指针是以地址为值的变量,而数组名的值的值是一个特殊的固定地址,可以把它看作是指针常量。

例1

int a[40],*p;

系统分别把编号为3000,3004,3008等的内存字节作为数组元素a[0],a[1],a[2]等的地址(假设int型变量的长度是4个字节)。其中内存位置3000是数组a的基地址,也是a[0]的地址。

例2

假设a[0]的地址为3000,int类型变量的长度为4字节。

p=a;
p=&a[0];

它们都把3000这个地址赋给了指针p。

p=a+1;
p=&a[1];

它们都把3004这个地址赋给了指针p。

例3

设已对a的数组元素进行了赋值

数组求和法一
sum=0;
for(p=a;p<=&a[99];p++)
    num+=*p;

在循环中,指针变量p的初值是数组a的基地址,p连续取值&a[0],&a[1],&a[2]等。

数组求和法二
sum=0;
for(i-0;i<100;i++)
     sum+=*(a+1);

*[a+i]与a[i]等价,*[p+i]与p[i]等价。

数组求和法三
p=a;
sum=0;
for(i=0;i<100;++i) 
   sum+=p[i];

数组名可以使用指针形式,而指针变量也可以使用转换为数组形式。