问答题[说明]
本程序的功能是给公司的员工Tom,Jack,Green增加薪水。三人的职位分别是programmer, Manager,CEO。
程序由6个类组成:WorkerTest是主类,programmer,Manager,CEO三个类,薪水增加的规则是 programmer的涨幅是5%;Manager的是10%;CEO也是Manager,但是它除了有Manager的涨幅,还有1000元的bonus。接口SalaryRaise提供了一个增加薪水的方法raise()。
[java程序]
public class WorkerTest {
public WorkerTest( ) {}
public static void main( String[] args) {
Programmer programmer = new Programmer( "Tom" ,3000);
Manager manager = new Manager( "Jack" ,4000);
CEO ceo = new CEO( "Green" ,4000);
Worker [] worker = new Worker[3];
programmer, raise( );
manager, raise( );
ceo. raise( );
worker[0] = programmer;
worker [1] = manager;
worker[2] = ceo;
for ( int i = 0 ;i < worker, length; i + + ) {
System. out. prinfln (" Name:" + worker [i]. getName ( ) +" / tSalary:" + worker [i]. getSalary ());
public interface SalaryRaise { void raise( ); }
public class Worker {
public String name;
public double{{U}} (1) {{/U}};
public Worker( ) {}
public String getName( ) {return name;}
public void setName( String name) {this. name = name;}
public double getSalary( ) {return salary;}
public void setSalary(double salary) { this. salary = salary; }
}
public class Programmer extends Worker implements{{U}} (2) {{/U}}{
public Programmer( ) {}
public void raise( ) {
double pets=0.05;
double sala = this. getSalary( ) * (1 + pers);
this. setSalary (sala);
public Programmer( Siring name, double salary) t
this. name = name;
this. salary = salary;
public class Manager extends{{U}} (3) {{/U}}implements SalaryRaise {
public Manager( ) { }
public Manager(String name, double salary) {
this. name = name;
this. salary = salary;
}
public void raise( ) {
double pets = 0.1;
double sala = this. getSalary() * (1 + pers);
this. setSalary(sala);
}
}
public class CEO extends Manager implements SalaryRaise {
public CEO() {}
public CEO( String name,double salary) {
this. name = name;
this. salary = salary;
}
public void raise( ) {
double bonus = 1000;
{{U}}(4) {{/U}};
double sala = this. getSalary( );
{{U}} (5) {{/U}};
this. setSalary(sala);
}
}
问答题阅读以下说明和C代码,填补代码中的空缺,将解答填入答题纸的对应栏内。
[说明]
下面的程序代码根据某单位职工的月工资数据文件(名称为Salary.dat,文本文件),通过调用函数GetIncomeTax计算出每位职工每月需缴纳的个人所得税额并以文件(名称为IncomeTax.dat,文本文件)方式保存。
例如,有4个职工工资数据的Salary.dat内容如下,其中第一列为工号(整数),第2列为月工资(实数)。
1030001 6200.00
1030002 5800.00
2010001 8500.00
2010010 8000.00
相应地,计算所得IncomeTax.dat的内容如下所示,其中第3列为个人所得税额:
1030001 6200.00 47.20
1030002 5800.00 35.94
2010001 8500.00 233.50
2010010 8000.00 193.00
针对工资薪金收入的个人所得税计算公式为:
个人所得税额=应纳税所得额×税率-速算扣除数
其中,应纳税所得额=月工资-三险一金-起征点
税率和速算扣除数分别与不同的应纳税所得额对应,如下表所示。
级数
全月应纳税所得额X(元)
税率(%)
速算扣除数(元)
1
0<X≤1500
3
0
2
1500<X≤4500
10
105
3
4500<X≤9000
20
555
4
9000<X≤35000
25
1005
5
35000<X≤55000
30
2755
6
55000<X≤80000
35
5505
7
X>80000
45
13505
设三险一金为月工资的19%,起征点为3500元。
例如,某人月工资为5800元,按规定19%缴纳三险一金,那么:
其应纳税所得额X=5800-5800×19%-3500=1198元,对应税率和速算扣除数分别为3%和0元,因此,其个人所得税额为1198×3%-0=35.94元。
[C代码]
#include <stdio.h>
#define BASE 3500 //起征点
#define RATE 0.19 //三险一金比例
______; //声明函数GetIncomeTax
int main()
{
int id;
double salary;
FILE *fin,*fout;
fin = fopen("Salary.dat","r");
if (______) return 0;
fout = fopen("IncomeTax.dat","w");
if (______) return 0;
while (!feof(fin)) {
if (fscanf(fin,"%d%if", ______) !=2) break;
fprintf(fout,"%d/t%.21f/t%.21f/n",id, salary, ______);
}
fclose(fin);
fclose(fout);
return 0;
}
double GetIncomeTax(double salary)
{
double yns_sd;
yns_sd = ______ - BASE; /*计算应纳税所得额*/
if (yns_sd<=0) return 0.0;
else if (yns_sd<=1500) return yns_sd*0.03;
else if (yns_sd<=4500) return yns_sd*0.1-105;
else if (yns_sd<=9000) return yns_sd*0.2-555;
else if (yns_sd<=35000) return yns sd*0.25-1005;
else if (yns_sd<=55000) return yns_sd*0.3-2755;
else if(yns_sd<=80000) return yns_sd*0.35-5505;
return yns_sd*0.45-13505;
}
问答题[说明]本程序实现的功能是查看磁盘上的图片及其基本信息。程序运行界面如下图所示,用户只要逐步选择适当的驱动器、目录和图片文件,图片内容随即显示在界面中央,文件的基本信息则呈现于右侧文本框中。用户还可以删除或复制选中的图片文件。在开发过程中,驱动器列表框名为Drivel,目录列表框名为Dir1,文件列表框名为File1,图片的显示由Image控件对象Image1来实现,文件信息文本框名为Text1,按钮“删除文件”和“复制到…”分别名为CmdDel和CmdCpy。[VisualBasic代码]DimfilenameAsStringDimfsoAsNew(1),fileAsfilePrivateSubForm_Load()Setfso=CreateObject("Scripting.FileSystemObject")Drivel.Drive="F:"EndSubPrivateSubDir1_Change()File1.path=Dirl.path’更新文件列表框的路径EndSubPrivateSubDrive1_Change()Dir1.path=(2)’更新目录列表框的路径EndSubPrivateSubFile1_Click()’文件列表框的单击事件响应代码IfRight(Dir1.path,1)<>"/"Thenfilename=Dir1.path&"/"&Filel.filenameElsefilename=Dir1.path&Filel.filenameEndIfImage1.Picture=(3)Setfile=fso.GetFile(filename)Text1.Text="文件名称:"&file.Name&vbCrLf&_"文件大小:"&file.Size&"字节"&vbCrLf&_"文件类型:"&file.Type&vbCrLf&_"创建日期:"&file.DateCreated&vbCrLf&_"修改日期:"&file.DateLastModifiedEndSubPrivateSubCmdCpy_Chck()’按钮“复制到…”的单击事件响应代码DimpathAsStringpath=InputBox("请输入目标路径(含文件名):")(4)EndSubPrivateSubCmdDel_Click()’按钮“删除文件”的单击事件响应代码(5)EndSub
问答题【说明】 已知某数列的前两项为2和3,其后继项根据当前最后两项的乘积按下列规则生成: (1)若乘积为一位数,则该乘积即为数列的后继项; (2)若乘积为二位数,则该乘积的十位数和个位数依次作为数列的两个后继项。 本程序输出该数列的前n项以及它们的和。其中,函数sum(n,pa)返回数列的前n项之和,并将生成的前n项存放于首指针为pa的数组中。程序中规定输入的n值必须大于2并且不超过给定的常数值MAXNUM。 例如:若输入n值为10,则程序输出如下内容: sum(10)=44 2 3 6 1 8 8 6 4 2 4 #include<stdio.h> #define MAXNUM 100 int sum(int n,int *pa) int count,total,temp; *pa=2; (1) =3; total=5; count=2; while(count++<n) temp+=*(pa-1)**pa; if(temp<10) total+=temp; *(++pa)=temp; else (2) =temp/10; total+=*pa; if(count<n) count++;pa++; (3) =temp%10; total+=*pa; (4) ; main() int n,*p,*q,num[MAXNUM]; do printf("Input N=?(2<N<%d):",MAXNUM+1); scanf("%d", while( (5) ); printf("/nsum(%d)=%d/n",n,sum(n,num)); for(p=num,q= (6) ;p<q;p++)printf("%4d",*p); printf("/n");
问答题【说明】 在下面函数横线处填上适当的字句,使其输出结果为: 构造函数. 构造函数. 1,2 5,6 析构函数 析构函数. 【C++代码】 #include "iostream.h" class AA public; AA(int i,int j) A=i; B=j; cout<<"构造函数./n"; ~AA() (1) ; void print(); private: int A, B; ; void AA∷print() cout<<A<<","<<B<<endl; void main() AA *a1, *a2; (2) =new AA(1, 2); a2=new AA(5, 6); (3) ; a2->print(); (4) a1; (5) a2;
问答题【说明】已知头指针分别为La和lb的有序单链表,其数据元素都是按值非递减排列。现要归并La和Lb得到单链表Lc,使得Lc中的元素按值非递减排列。程序流程图如下所示:
问答题【说明】 以字符流形式读入一个文件,从文件中检索出6种C语言的关键字,并统计、输出每种关键字在文件中出现的次数。本程序中规定:单词是一个以空格或'/t'、'/n'结束的字符串。其中6种关键字在程序中已经给出。 【程序】 #include <stdio.h> #include <stdlib.h> FILE *cp; char fname[20], buf[100]; int NUM; struct key char word[10]; int count; keyword[]= "if", 0, "char", 0, "int", 0, "else", 0, "while", 0, "return", 0; char *getword (FILE *fp) int i=0; char c; while((c=getc(fp))!= EOF if(c==EOF) return (NULL); else buf[i++]=c; while((c=fgetc(fp))!=EOF buf[i]='/0'; return(buf); void lookup(char *p) int i; char *q, *s; for(i=0; i<NUM; i++) q= (2) ; s=p; while(*s break; return; void main() int i; char *word; printf("lnput file name:"); scanf("%s", fname); if((cp=fopen(fname, "r"))==NULL) printf("File open error: %s/n", fname); exit(0); NUM=sizeof(keyword)/sizeof(struct key); while( (5) ) lookup(word); fclose(cp); for(i=0;i<NUM;i++) printf("keyword:%-20s count=%d/n",keyword[i].word,keyword[i].count);
问答题【说明】 本程序从若干个原始文件合并成的合并文件中恢复出其中一个或全部原始文件。所有文件均作为二进制文件进行处理。合并文件中先顺序存储各原始文件,然后顺序存储各原始文件的控制信息,即文件名、文件长度和在合并文件中的位置(偏移量)。其结构为: typedef struct char fname [256] /*原始文件名*/ long length; /*原始文件长度(字节数)*/ long offset; /*原始文件在合并文件中的位置(偏移量)*/ FileInfo; 在合并文件最后存储如下一个特殊的标志信息作为合并文件的结束标记: FileInfo EndFlag="Combined File",0,_offset; 其中_offset是第一个原始文件的控制信息在合并文件中的位置(偏移量)。 启动本程序的命令行的格式是: 程序名 合并文件名 [原始文件名] 如果不指定原始文件名,默认恢复合并文件中的所有原始文件。 程序中涉及的部分文件操作的库函数简要说明如下: int fread(void * buffer,int size,int count,FILE * fbin):从二进制文件流fbin中读取 count块长度为size字节的数据块到buffer指向的存储区。返回值为实际读取的数据块数。 int fwrite(void * buffer,int size,int count,FILE * fbin):各参数和返回值的意义与fread相同,但对文件进行写操作。 int fseek(FILE * fbin,long offset,int position):将文件流fbin的读/写位置以position为基准移动offset字节。position的值可以是SEEK_SET(文件头),SEEK_CUR(当前位置), SEEK_END(文件尾);offset为正,表示向文件尾方向移动,为负表示向文件头方向移动,为零表示到基准位置。 long ftell(FILE * fbin):返回文件流fbin的当前读/写位置(相对于文件头的偏移量)。上述偏移量均以字节为单位,即偏移字节数。 【程序】 #include <stdio. h> #include <string. h> typedef struct char fname[256];long lengt;long offset; Filelnfo; void copyfile( FILE*fin, FILE * fout,int fsize) char buf[1024];int siz=1024; while(fsize !=0) /*每次复制siz个字节,直至复制完fsize个字节*/ if(siz >fsize) (1) ; fread(buf,1,siz,fin); fwrite(buf,1,siz,fout); fsize= (2) ; int dofile(FILE * fin,Filelnfo * inp) long offset; FILE * fout; if (( fout = fopen ( inp - > fname ,"wb" ))==NULL) printf("创建文件错误: %s/n" , inp -> fname); return 1; offset= (3) ; /*保留合并文件读/写位置*/ fseek( (4) ); /*定位于被恢复文件首*/ copyfile ( fin, fout, inp - > length); fclose(fout); printf("/n ---文件名: %/n 文件长: %ld. /n",inp -> fname, inp -> length); (5) ; /*恢复合并文件读/写位置*/ return 0; int main( int argc, char * argv[ ]) Filelnfo finfo; char fname[256] ;FILE * fcmbn; if(argc <2) printf("输入合并文件名:" ) ;scanf("%s" ,fname); else strcpy(fname,argv[1]); if((fcmbn = fopen(fname,"rb" )) == NULL) printf("文件打开错误: %s/n" ,fname);return 1; fseek(fcmbn, -sizeof(Filelnfo),SEEK_END); /*定位于合并文件末尾的标志信息*/ fread( if(finfo. length!=0||strcmp(finfo. fnane," CombinedFile" )) printf("指定的文件不是合法的合并文件/n"); fclose (fcmbn); return 2; fseek(fcmbn,finfo. offset,SEEK_SET); /*定位于首个原始文件的控制信息*/ for(;;) /*恢复一个(argc>2)或全部(argc=2)原始文件*/ fread ( if(finfo, length ==0) break; if (argc> 2 if (dofile ( fcmbn, fcolse(fcmbn);return 0;
问答题【说明】 下面代码里,instr是一个抽象类,它被两个子类wind和rain分别实现,而brass又继承了wind类,并覆盖了play方法。 【程序】 (1) class instr (2) Void play(); class wind (3) instr void play()System.out.println("wind play!"); class rain extends instr void play()System.out.println("rain play!"); class brass extends (4) void play()System.out.println("brass play!")); public class music static void tuneAll(instr e[]) for(int i=0;i<e.length;i++) e[i].play(); public (5) void main(String[]args) instr orch[]=new instr[3]; int i=0; orch[i++]=new wind(); orch[i++]=new rain(); orch[i++]=new brass(); tuneAll(orch);
问答题【说明】 Stack类是java. ntil包中专门用来实现栈的工具类。以下Java程序是一个不使用库函数而实现字符串反转的程序。例如,输入:123456,则输出:654321:输入:asdfeg,则输出:gefdsa。【Java程序】import java.applet.Applet;import java.awt.*;import java.awt.event.*;import java.util.*;public class UseStack extends Applet implements ActionListener Stack MyStack; Label prompt=new Label("输入要反转字符:"); Button pushBtn=new Button("压栈"); Button popBtn=new Button("弹栈"); //反转 TextField input=new TextField(5); int[] DrawStack =new int[10]; //记录堆栈中数据 int[] PoppedOut=new int[20]; //记录被弹出的数据 int StackCnt=0; //记录模拟堆栈的数组中的数据个数 String msg=" "; public void init() MyStack=new Stack(); add(prompt); add(input); add(pushBtn); add(popBtn); pushBtn.addActionListener(this); (1) public void paint(Graphics g) for (int i=10; i<StackCnt; i++) //模拟显示堆栈内部的数据排列情况 g.drawRect(50,200-i*20,80,20); g.drawString(Integer.toString(DrawStack[i]),80,215-i*20); for (int i=0; (2) ) //显示被弹出的数据 g.drawString(Integer.toString(PoppedOut[i]),200+i*20,100); g.drawString("堆栈",70,236); g.drawString("栈底",135,225); g.drawString("栈顶",160,225-StackCnt*20); g.drawString(msg,200,140); public void actionPerformed( (3) ) if (e.getAct ionCommand () == "压栈") //压栈操作 if(StackCnt<10) MyStack.push(new Integer( (4) )); DrawStack[StackCnt++]=Integer.parseInt(input.getText() ); input.setText (" "); else msg="输入数据过多,请先弹栈!" else if (e.getActionCommand () == "弹栈") //弹栈操作 if( (5) ) StackCnt--; PoppedOut[PopCnt++]=[(Integer)(MyStack.pop())).intValue(); else msg="堆栈已空,不能再弹栈!"; repaint();
问答题阅读以下说明、C函数和问题,将解答写入答题纸的对应栏内。
{{B}}[{{/B}}说明1{{B}}]{{/B}}
函数test_f1(int m,int n)对整数m、n进行某种运算后返回一个整数值。
{{B}}[{{/B}}C函数1{{B}}]{{/B}}
int test_f1(int m,int n)
{ int k;
k=m>n? m:n;
for(;(k% m! =0) ||(k% n! =0);k++);
return k;
}
{{B}}[{{/B}}问题1{{B}}]{{/B}}
(1)请写出发生函数调用test_f1(9,6)时,函数的返回值;
(2)请说明函数test_f1的功能。
{{B}}[{{/B}}说明2{{B}}]{{/B}}
设在某C系统中为每个字符分配1个字节,为每个指针分配4个字节,sizeof(x)计算为 x分配的字节数。
函数test_f2()用于测试并输出该C系统为某些数据分配的字节数。
{{B}}[{{/B}}C函数2{{B}}]{{/B}}
void test_f2( )
{ char str[] ="NewWorld"; char* p=str; char i ='/0';
void* ptr =malloc(50);
printf("% d/t",sizeof(str)); printf("% d/n",sizeof(p));
printf("% d/t",sizeof(i)); printf("% d/n",sizeof(ptr));
}
{{B}}[{{/B}}问题2{{B}}]{{/B}}
请写出函数test_f2()的运行结果。
{{B}}[{{/B}}说明3{{B}}]{{/B}}
函数test_f3(char s[])的功能是:将给定字符串s中的所有空格字符删除后形成的串保存在字符数组tstr中(串s的内容不变),并返回结果串的首地址。
{{B}}[{{/B}}C函数3{{B}}]{{/B}}
char*test_f3 (const char s[])
{ char tstr[50] = {'/0'}; unsigned int i, k=0;
for (i =0;i<strlen(s);i++)
if(s[i]! =") tstr[k++]=s[i];
return tstr;
}
{{B}}[{{/B}}问题3{{B}}]{{/B}}
函数test_f3()对返回值的处理有缺陷,请指出该缺陷并说明修改方法。
问答题【说明】 以下程序的功能是:从键盘上输入一个字符串,把该字符串中的小写字母转换为大写字母,输出到文件test.txt中,然后从该文件读出字符串并显示出来。 【程序】 #include < stdio. h > main( ) FILE * fp; char str[100]; int i=0; if((fp=fopen("text.txt" (1) )) ==NULL) printf("can't open this file. /n") ;exit(0) ; printf(" input astring: /n" ); gest(str); while( str[i] ) if(str[i] >='a' fputc(str[i], (3) ); i++; fclose(fp); fp=fopen(" test.txt", (4) ); fgets(str, 100, fp); printf("%s/n" ,str); (5) ;
问答题
问答题[说明] 下面的程序利用递归算法计算x和y的最大公约数。[函数2.1] main ( ) int x,y,k,t; scanf(" % d% d" , if(x>y) t=x;x=y; y=t; (1) ; while(k! =0) y=x; (2) ; k=y%x; prinff( "% d" ,x); [函数2.2说明] 函数fun(char *str,char *substr的功能是计算子串sugbstr在串str中出现的次数。[函数2.2]fun(ehar * str, char * substr) int x,y,z; (3) ; for(x=0;str[ x] ! = '/O';x + + ) for(y=x,z=0;sabstr[z] = =str[y]; (4) ,y+ +) if( (5) = ='/0') num + +; break; return(num);
问答题[说明] 用链式存储结构实现的栈称为链栈。若链栈元素的数据类型为datatype,以LinkStack记链栈结构,其类型定义为:typedef struct node datatype data; stmct node * next; StackNode, * LinkStack; 由于栈的主要操作都是在栈顶进行的,因此我们把链表的头部作为栈顶。设top为栈顶指针,即:LinkStack top。 下面各函数的功能说明如下: (1)LinkStack Init_LinkStack():建立并返回空的链栈; (2)int Empty_LinkStack(LinkStack top):判断top所指链栈是否空; (3)LinkStack Push_LinkStack(LinkStacktop,datatypex):将数据x压人top所指链栈的栈顶,返回新栈指针; (4)LinkStack Pop_LinkStack (LinkStacktop, datatype*x):弹出top所指链栈的栈顶元素x,返回新栈指针。[函数] LinkStaek Init_LinkStack( ) returnNULL;int Empty_LinkStack ( LinkStaek top) if(top = = NULL) return 1; else return 0;LinkStaek Push_LinkStaek( LinkStaektop, datatype X) StaekNode *s; s=malloc (sizeof(StaekNode) ); (1) = x; (2) = top; (3) ; return top;LinkStaek Pop_LinkStack (LinkStacktop, datatype * x) StaekNode *p; if(top = = NULL) return NULL; else * x = (4) ; p = top; (5) ; free (p); return top;
问答题阅读以下说明和C函数,填补C函数中的空缺(1)~(5),将解答写在答题纸的对应栏内。[说明]函数SetDiff(LA,LB)的功能是将LA与LB中的共有元素从LA中删除,使得LA中仅保留与LB不同的元素,而LB不变,LA和LB为含头结点的单链表的头指针。例如,单链表LA、LB的示例如图4-1中的(a)、(b)所示,删除与LB共有的元素后的LA如图4-1中的(c)所示。函数SetDiff(LinkListLA,LinkListLB)的处理思路如下:(1)从LA的第一个元素结点开始,令LA的第一个元素为当前元素。(2)在LB中进行J顷序查找,查找与LA的当前元素相同考,方法是令LA的当前元素先与LB的第一个元素进行比较,若相等,则结束在LB中的查找过程,否则继续与LB的下一个元素比较,重复以上过程,直到LB中的某一个元素与LA的当前元素相等(表明查找成功),或者到达LB的表尾(表明查找失败)为止。(3)结束在LB表的一次查找后,若在LB中发现了与LA的当前元素相同者,则删除LA的当前元素,否则保留LA的当前元素。(4)取LA的下一个元素为当前元素,重复(2)、(3),直到LA的表尾。
问答题【应用说明】某应用的登录界面如下:登录界面中的文本框txtUserID和txtPassword分别用于接受用户输入的用户名和口令,命令按钮为“确定(cmdOk)”和“取消(cmdCancel)”。ADO数据控件Adodc1与数据库EmployeeData连接。在EmployeeData中,表“Users”的字段“UserID”和“Pswd”分别记录了所有的合法用户名和口令。在登录界面中,输入正确的用户名和口令并单击“确定”按钮后,就会打开应用程序的主窗口fxmApp。用户名或密码输入错误时,给出提示信息并返回登录界面。【VisualBasic程序代码】PrivateSubcmdOKClick()Adodcl.ConnectionString="Provider=Microsoft.Jet.OLEDB.4.0;DataSource=D:/data/EmployeeData.mdb;PersistSecurityInfo=False"Adodcl.RecordSource="select*{{U}}(1){{/U}}"Adodcl.RefreshDousrname={{U}}(2){{/U}}pwd=Adodc1.Recordset("Pswd")Adodc1.Recordset.MoveNextLoopUntil(usrname={{U}}(3){{/U}})Or(Adodc1.Recordset.EOF)Ifusrname<>txtUserID.TextThenMsgBox"无效的用户ID,请重新输入!",,"提示信息"ElseIf{{U}}(4){{/U}}ThenMsgBox"欢迎进入系统主界面!",,"提示信息"Unloadme{{U}}(5){{/U}}ElseMsgBox"无效的用户密码,请重新输入!",,"提示信息"EndIfEndIfEndSub
问答题【说明】假设数组A中的各元素A(1),A(2),…,A(M)已经按从小到大排序(M≥1);数组B中的各元素B(1),B(2),…,B(N)也已经按从小到大排序(N≥1)。执行下面的流程图后,可以将数组A与数组B中所有的元素全都存入数组C中,且按从小到大排序(注意:序列中相同的数全部保留并不计排列顺序)。例如,设数组A中有元素:2,5,6,7,9;数组B中有元素2,3,4,7:则数组C中将有元素:2,2,3,4,5,6,7,7,9。【流程图】
问答题阅读以下说明和C函数,填充函数中的空缺,将解答填入答题纸的对应栏内。
【说明】
函数GetDateld(DATE date)的功能是计算并返回指定合法日期date是其所在年份的第几天。例如,date表示2008年1月25日时,函数的返回值为25,date表示2008年3月3日时,函数返回值为63。
函数Kday_Date(int theyear,int k)的功能是计算并返回指定合法年份theyear(theyear≥1900)的第k天(1≤k≤365)所对应的日期。例如,2008年的第60天是2008年2月29日,2009年的第60天是2009年3月
1日。
函数isLeapYear(int y)的功能是判断Y代表的年份是否为闰年,是则返回1,否则返回0。
DATE类型定义如下:
typedef struct{
int year,month,day;
}DATE;
【C函数1】
int GetDateId(DATE date)
{
Const int days_month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int i,date_id=date.day;
for(i=0;i=1&&k=1900);/*不满足断言时程序终止*/
date.year=____(4)____;
if(isLeapYear(date.year))days_month[2]++;
for(i=1;;){
k=k—days_month[i++];
if(k<=0){date.day=k+____(5)____;date.month=i一1;break;}
}
return date;
}
问答题【说明】
著名的四色定理指出任何平面区域图均可用4种颜色着色,使相邻区域着不同的颜色。以下C程序对给定的区域图找出所有可能的不超过4种颜色的着色方案。该程序中用1~4分别表示4种颜色。要着色的N个区域用0~-1编号,区域相邻关系用adj[][]矩阵表示,矩阵的i行j列的元素为1,表示区域i与区域了相邻;矩阵的i行j列的元素为0,表示区域i与区域j不相邻。数组color[]用来存储着色结果,color[i]的值为区域i,所着颜色。
【C程序】
#include <stdio.h>
#define N 10
void output(int color[]) { /*输出一种着色方案*/
int i ;
for ( i = 0 ; i < N ; i++ )
printf( "%4d" , color[i] ) ;
printf ("/n") ;
}
int back(int *ip ,int color[] ) { /*回溯*/
intc = 4 ;
while ( c == 4 ) {
if ( *ip <= 0 )
return 0 ;
-- (*ip) ;
c ={{U}} (1) {{/U}};
color[*ip] =-1 ;
}
return c ;
}
/*检查区域i,对c种颜色的可用性*/
int colorOk(int i , intc , int [] [N] ,int color[ ] ) {
int j ;
for (j = 0 ; j < i ; j++ )
if ({{U}} (2) {{/U}})
return 0 ;
return 1 ;
}
/*为区域i选一种可着色的颜色*/
int select (int i ,int c ,int adj [] [N] ,int color[ ] ){
int k ;
for(k = c ; k <= 4 ; k++ )
if( colorOK({{U}} (3) {{/U}}))
return k ;
return 0 ;
}
int coloring(int adj [] [N]) { /*寻找各种着色方案*/
int color[N] , i , c , cnt ;
for(i = 0 ; i < N ; i++)
color[i] =-1 ;
i = c = 0 ;
cnt = 0 ;
while(1) {
if((c ={{U}} (4) {{/U}}) == 0 {
c = back(
if( c == 0 )
return cnt;
}
else {
{{U}} (5) {{/U}};
i++ ;
if i == N) {
output(color);
++cnt ;
c = back(
}
else c = 0 ;
}
}
}
void main()(
int adj[N] [N] =
{ {0,1,0,1,1,1,1,1,1,1},
{1,0,1,1,0,1,1,1,1,0},
{0,1,0,1,0,1,1,0,1,1},
{1,1,1,0,1,1,0,0,1,1},
{1,0,0,1,0,1,0,0,0,0},
{1,1,1,1,1,0,1,0,0,1},
{1,1,1,0,0,1,0,0,1,0},
{1,1,0,0,0,0,0,0,1,1},
{1,1,1,1,0,0,1,1,0,1},
{1,0,1,1,0,1,0,1,1,0},
} ;
printf("共有%d组解./n",coloring(adj));
}
