背景:拱猪是一种很有趣的扑克牌游戏。即使你不知道它的玩法,你也可以由它的计分方式来了解它的趣味性。 假设在此我们仅考虑四个人的拱猪牌局,本题要求你根据下面的计分规则,在牌局结束时计算四位玩家所得分数。
我们分别以S、H、D及C来代表黑桃,红心,方块及梅花,并以数字1至 13来代表A、2、?、Q、K等牌点,例如:H1为红心A,S13为黑桃K。 牌局结束时,由各玩家持有的有关计分的牌(计分牌)仅有S12(猪),所有红心牌,D11(羊)及C10(加倍)等16张牌。其它牌均弃置不计。若未持有这16张牌之任一张则以得零分计算。
若持有C10的玩家只有该张牌而没有任何其它牌则得+50分,若除了C10 还有其它计分牌,则将其它计分牌所得分数加倍计算。
若红心牌不在同一家,则H1至H13等13张牌均以负分计,其数值为-50, -2,-3,-4,-5,-6,-7,-8,-9,-10,-20,-30,-40。而且S12与D11分别以-100及+100分计算。
若红心牌H1至H13均在同一家,有下列情形: 所有红心牌以+200分计算。
若S12、D11皆在吃下所有红心牌之一家,则此玩家得+500分。
而C10还是以前面所述原则计算之。
例一:若各玩家持有计分牌如下: ( 每行代表一玩家所持有之牌 ) S12 H3 H5 H13 D11 H8 H9
C10 H1 H2 H4 H6 H7 H10 H11 H12
则各家之得分依序为: -148 、 +83 、 -138 及 -60 。
例二:若各玩家持有计分牌如下:(第四家未持有任何计分牌)
H1 H2 H3 H4 H5 H6 H7 H8 H9 H10 H11 H12 H13 S12 C10 D11
则各家之得分依序为: +200 、 -200 、 +100 及 0 。
例三:若有一玩家持有所有 16 张计分牌,则得 +1000 分。其余三家均得零分。
输入:每个输入文件由多组测试数据构成,每组测试数据有四行,每一行第一个数为该玩家所持有计
分牌总数,而后列出其所持有之所有计分牌,牌数与各计分牌均以一个以上的空格分开。相邻两组测试数据之间不会有空白行,读到四家持牌数都为 0 表示文件结束。
输出:每一行输出一组测试数据对应的结果,依次输出各家所得分数,共四个整数 ( 含正负号,0 除外),相邻两个整数之间以一个空格分开,符号和数字间不可以有空格。每组输出间不需要有空白行。 #include \
int myinput(int card[],int number[]) {
int i,n; char s[5];
for(i=0;i<4;i++) {
scanf(\ number[i]=n; while(n--) {
scanf(\ switch(s[0]) {
case 'S':card[13]=i;break; case 'D':card[14]=i;break; case 'C':card[15]=i;break; case
'H':s[2]=='\\0'?(card[s[1]-'1']=i):(card[s[2]-'1'+10]=i); } } } return
number[0]+number[1]+number[2]+number[3]; }
int main() {
int
value[15]={-50,-2,-3,-4,-5,-6,-7,-8,-9,-10,-20,-30,-40,-100,100},
card[16],
score[4]={0,0,0,0}, number[4], i,s,
- 36 -
input();
while(myinput(card,number)) {
for(i=0,s=0;i<13;i++) s+=card[i]; if(s) {
for(i=0;i<15;i++)
score[card[i]]+=value[i]; } else {
if(card[0]==card[13]&&card[13]==card[14]) score[card[0]]+=500; else {
score[card[0]]+=200;
score[card[14]]+=value[14]; score[card[13]]+=value[13]; } }
score[card[15]]+=number[card[15]]==1?50:score[card[15]];
for(i=0;i<4;i++)
printf(\:\
for(i=0;i<4;i++) score[i]=0; }
return 0; }
选作T 8.2 合并果子
在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。
每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。
因为还要花大力气把这些果子搬回家,所以多多在
合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。 例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。 输入:输入包括两行,第一行是一个整数n(1<=n<=10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=10000)是第i种果子的数目。
输出: 输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于231。
#include
int i,j,k,t,n,sum=0; int a[10]={0}; int b[10]={0}; char s[10][100]; scanf(\ for(i=1;i<=n;i++) scanf(\ for(t=1;t<=n;t++) a[t]=strlen(s[t]); for(i=1;i<=n;i++) for(j=0;j
for(i=0;i<=a[j]/2-1;i++) {
t=s[j][i];
s[j][i]=s[j][a[j]-1-i]; s[j][a[j]-1-i]=t; } }
for(j=1;j<=n;j++)
- 37 -
{
for(i=0;i<=a[j];i++) {
b[j]=b[j]+s[j][i]*pow(10,i); } }
for(j=1;j<=n-1;j++) for(i=1;i<=n-j;i++) {
if(b[i]>b[i+1]) {
t=b[i];
b[i]=b[i+1]; b[i+1]=t; } }
sum=(n-1)*(b[1]+b[2]); for(i=2;i<=n-1;i++) sum=sum+(n-i)*b[i+1]; printf(\}
选作T 8.3 安全的密码
随着电子设备的广泛运用,密码也渐渐融入每个人的生活。保护好密码,不仅关系到个人隐私,更关系到个人的财产和安全。一个安全的密码,最好由大小写字母、数字或符号组成。包含越多种类的字符,其安全性就越高。同时密码还需要有一定的长度,通常至少要由六个以上的字符组成。
并不是每个人都喜欢这样复杂的密码,很多人在设置密码的时候,喜欢使用自己的名字或者生日,但这是很大的安全隐患。 任务
小林正在设计一个网络交易系统,为了保证用户的密码安全,他需要一个程序,判断用户自己设置的密码是否安全,如果不安全,则给出提示。现在他向你求助,请你帮忙设计一个程序来解决这个问题。 应当按照以下的规则来判断密码是否安全: 如果密码长度小于 6 位,则不安全
如果组成密码的字符只有一类,则不安全 如果组成密码的字符有两类,则为中度安全 如果组成密码的字符有三类或以上,则为安全 通常,可以认为数字、大写字母、小写字母和其它符号为四类不同的字符。
输入:输入的第一行是一个整数 N,表明后面有多少
组密码。随后的 N 行输入包括 N 个密码,每个密
码的长度均小于 20 个字符。
输出:针对每一个密码判断并输出它是否安全。对于不安全的密码输出 \Safe\,对于中度安全的密码输出 \Safe\,对于安全的密码输出 \输入样例
41234abcdefABC1231#c3Gh输出样例 Not SafeNot SafeMedium SafeSafe #include
int n,i,j,k,t,flag1=0,flag2=0,flag3=0,flag4=0; char s[20][50]; scanf(\ for(i=0;i<=n;i++) gets(s[i]);
for(i=1;i<=n;i++) {
t=strlen(s[i]); if(t<6)
printf(\ if(t>=6) {
for(flag1=0,flag2=0,flag3=0,flag4=0,j=0;s[i][j]!='\\0';j++)
{
if(s[i][j]>=48&&s[i][j]<=57) flag1++;
if(s[i][j]>=65&&s[i][j]<=90) flag2++;
if(s[i][j]>=97&&s[i][j]<=122) flag3++;
if((s[i][j]>=33&&s[i][j]<=47&&s[i][j]>=58&&s[i][j]<=64&&s[i][j]>=91&&s[i][j]<=96&&s[i][j]>=123&&s[i][j]<=126)||(s[i][j]==' ')) flag4++; }
if(flag1==t||flag2==t||flag3==t||flag4==t) printf(\
- 38 -
if((flag1*flag2>0&&flag3==0&&flag4==0)||(flag1*flag3>0&&flag2==0&&flag4==0)||(flag1*flag4>0&&flag2==0&&flag3==0)||(flag2*flag3>0&&flag1==0&&flag4==0)||(flag2*flag4>0&&flag3==0&&flag1==0)||(flag3*flag4>0&&flag1==0&&flag2==0)) printf(\
if((flag1*flag2*flag3>0&&flag4==0)||(flag1*flag2*flag4>0&&flag3==0)||(flag1*flag4*flag3>0&&flag2==0)||(flag4*flag2*flag3>0&&flag1==0)||(flag1*flag2*flag3*flag4>0))
printf(\ } } }
选作T 8.4 扫雷
背景 :你玩儿过扫雷游戏吧?有个操作系统中带了这个小游戏,那个系统叫什么来着?在游戏中要想过关,就必须要在一个 NxM 的区域上找出所有的地雷。游戏过程中,计算机会在地图上显示一些数字从而帮助你确定哪里有地雷。例如,在下面这个有两颗地雷的 4x4 的地图(*表示地雷):
*........*...... 根据上面的地图,可以计算出应该提供给游戏者的数字如下所示:
*10022101*101110 每个数字表示了该方格周围到底有几个地雷,当然,一个方格周围最多的时候只会有八个。
输入 :输入中将包括一系列的地图,每个地图的第一行有两个整数 n 和 m(0 Field #x:其中 x 是当前地图的编号(从 1 开始)。下面的 n 行则将地图中的 \以数字表示,该数字表示该方格周围有多少颗地雷。 #include int i,j,k,t=1,x1,x2; int n[100],m[100]; char c[100][100][100]; char s[100][100][100]; for(k=1;k<=N;k++) { scanf(\ if(n[k]==0&&m[k]==0) break; t++; for(j=0;j scanf(\ } for(j=0;j for(i=0;i for(i=0;i if(c[k][j][i]=='*') { s[k][j][i]=c[k][j][i]; } } } for(j=0;j for(i=0;i if(c[k][j][i]=='*') { s[k][j][i]=c[k][j][i]; if(j==0&&i==0) { for(x1=0;x1<=1;x1++) for(x2=0;x2<=1;x2++) if(s[k][j+x1][i+x2]!='*') { s[k][j+x1][i+x2]++; } } if(j==0&&i>0) { for(x1=0;x1<=1;x1++) - 39 - for(x2=-1;x2<=1;x2++) if(s[k][j+x1][i+x2]!='*') { s[k][j+x1][i+x2]++; } } if(i==0&&j>0) { for(x1=-1;x1<=1;x1++) for(x2=0;x2<=1;x2++) if(s[k][j+x1][i+x2]!='*') { s[k][j+x1][i+x2]++; } } if(i>0&&j>0) { for(x1=-1;x1<=1;x1++) for(x2=-1;x2<=1;x2++) if(s[k][j+x1][i+x2]!='*') { s[k][j+x1][i+x2]++; } } } } } } for(k=1;k<=t-1;k++) { printf(\ for(j=0;j for(i=0;i if(k!=t-1) printf(\ } } 选作T8.5 身份证的奥秘 背景18位身份证标准在国家质量技术监督局于1999年7月1日实施的GB11643-1999《公民身份号 码》中做了明确的规定。 GB11643-1999《公民身份 号码》为GB11643-1989《社会保障号码》的修订版,其中指出将原标准名称\社会保障号码\更名为\公民身份号码\,另外GB11643-1999《公民身份号码》从实施之日起代替GB11643-1989。GB11643-1999《公民身份号码》主要内容如下: 一、范围 该标准规定了公民身份号码的编码对象、号码的结构和表现形式,使每个编码对象获得一个唯一的、不变的法定号码。 二、编码对象 公民身份号码的编码对象是具有中华人民共和国国籍的公民。 三、号码的结构和表示形式 1、号码的结构 公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。 2、地址码 表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按GB/T2260的规定执行。 3、出生日期码 表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日代码之间不用分隔符。 4、顺序码 表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。 5、校验码 (1)十七位数字本体码加权求和公式 S = Sum(Ai * Wi), i = 0, ... , 16 ,先对前17位数字的权求和 Ai: 表示第i位置上的身份证号码数字值 Wi: 表示第i位置上的加权因子 Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 (2)计算模 Y = mod(S, 11) (3)通过模得到对应的校验码 Y: 0 1 2 3 4 5 6 7 8 9 10 校验码: 1 0 X 9 8 7 6 5 4 3 2 四、举例如下: 北京市朝阳区: 11010519491231002X 广东省汕头市: 440524188001010014 - 40 -