做题技巧总结:
1.前缀和数组
2.双指针,快慢指针
3.递归
4.qsort使用
5.结构体的使用
6.测试样例有部分不能通过,考虑一下特殊情况
易错点:
1.gets函数对同一个字符数组输入时,后一次输入会覆盖前一次的输入
2.当qsort按照结构体的某个元素排序结构体时,大小填的是结构体的大小
3.分支循环语句记得break
4.将整数以十六进制形式输出,用%x或%X(大写和小写)
5.打印 long long用%lld
6.字符数组是用\0表示为空
int a[10] = {0},数组里的数都被初始化为0
但是char b[10] = {0},数组里的数被初始化为 \0
7.
【程序1】 发红包
从2018年1月1日开始,小明每天给Angela发一个红包,红包金额的单位为元(¥),其中:金额的整数部分与月份相同,金额的小数部分与日期相同。具体的红包金额如下所示:
现在请你计算:截止于2018年某个具体的日期,小明发给Angela的红包金额总数是多少?
14:20-14:32
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
int main(){
int days[13] = {31,28,31,30,31,30,31,31,30,31,30,31};
int y,m,d;
scanf("%d%d%d",&y,&m,&d);
double sum = 0;
int i = 0,j = 0;
for(i = 1;i<m;i++){
sum+=days[i-1]*i;
for(j = 1;j<=days[i-1];j++){
if(j<10){
sum+=0.1*j;
}
else{
sum+=0.01*j;
}
}
}
sum += m*d;
for(j = 1;j<=d;j++){
if(j<10){
sum+=0.1*j;
}
else{
sum+=0.01*j;
}
}
printf("%.2f",sum);
}
【程序2】IDENTITY V
Yuki最近迷上了一款叫作IDENTITY V(第五人格)的游戏,六一节快到了,游戏也推出了一个活动。在活动期间,使用不同的角色参与对战,根据玩家在该局游戏中的表现会给予该角色相应的演绎积分,当演绎积分到达2000时,可以兑换相应角色的动态头像。该游戏现有的典型角色如下:
Yuki十分想要得到动态头像,每个玩家只能获得一个角色的动态头像,如果某一角色的积分足够,他会立即兑换。请根据Yuki在活动期间的对战情况,看看Yuki能够得到哪个角色的头像。
【测试样例1】 5 2 Doctor 500 Gardener 600 2 Doctor 500 Gardener 600 3 Machinist 600 Doctor 500 Machinist 800 1 Doctor 500 1 Machinist 800 【测试样例2,请注意这一组的角色名称】 3 2 ZXY 900 YWH 500 1 CXW 400 1 WSY 600
【测试样例1】 Doctor 【测试样例2】 NOTHING
14:36-14:56
要注意c语言中字符串不能直接赋值,要用到strcpy
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
struct Role{
int score;
char name[21];
}role[200];
int count = 0;//记录角色数量
//若已有此角色,返回该角色下标
int check_name(char name[]){
for(int i = 0;i<count;i++){
if(strcmp(role[i].name,name)==0){
return i;
}
}
return -1;
}
int check_score(){
for(int i = 0;i<count;i++){
if(role[i].score>=2000){
return i;
}
}
return -1;
}
int main(){
int T,n;
int i = 0;
int score;
char name[21];
scanf("%d",&T);
for(i = 0;i<T;i++){
scanf("%d",&n);
for(int j = 0;j<n;j++) {
scanf("%s %d\n",&name,&score);//输入加上\n
int index = check_name(name);
if(index>=0){
role[index].score += score;
}
else{
strcpy(role[count].name,name);
role[count].score = score;
count++;
}
index = check_score();
if(index>=0){
printf("%s",role[index].name);
return 0;
}
}
}
printf("NOTHING");
return 0;
}
【程序3】四边形的面积
已知平面上四点P1、P2、P3、P4的坐标,分别为(X1,Y1)、(X2,Y2)、(X3,Y3)、(X4,Y4)
如果将P1P2连线的中点A、P2P3连线的中点B、P3P4连线的中点C以及P4P1连线的中点D连接为一个新的四边形,你能否计算出四边形ABCD的面积?
在平面几何中,ABCD被定义为中点四边形。容易证明:ABCD为平行四边形
主要是海伦公式计算三角形面积
#include<stdio.h>
struct Node{
double x;
double y;
}p_node[4],node[4];
int main()
{
int i = 0;
for(i = 0;i < 4;i++){
scanf("%lf%lf",&p_node[i].x,&p_node[i].y);
}
//点A
node[0].x = (p_node[0].x+p_node[1].x)/2;
node[0].y = (p_node[0].y+p_node[1].y)/2;
//点B
node[1].x = (p_node[1].x+p_node[2].x)/2;
node[1].y = (p_node[1].y+p_node[2].y)/2;
//点C
node[2].x = (p_node[2].x+p_node[3].x)/2;
node[2].y = (p_node[2].y+p_node[3].y)/2;
//点D
node[3].x = (p_node[0].x+p_node[3].x)/2;
node[3].y = (p_node[0].y+p_node[3].y)/2;
double AC = sqrt((node[0].x-node[2].x)*(node[0].x-node[2].x)+(node[0].y-node[2].y)*(node[0].y-node[2].y));
double AB = sqrt((node[0].x-node[1].x)*(node[0].x-node[1].x)+(node[0].y-node[1].y)*(node[0].y-node[1].y));
double BC = sqrt((node[1].x-node[2].x)*(node[1].x-node[2].x)+(node[1].y-node[2].y)*(node[1].y-node[2].y));
double s = (AB+BC+AC)/2;
double S = sqrt(s*(s-AB)*(s-BC)*(s-AC));
printf("%.2f",S*2);
return 0;
}
【程序4】姓名缩写
用全拼查找人名比较麻烦,如果通过缩写查找姓名会方便很多。现给出n(1≤n≤100)个人的姓名全拼和一个姓名缩写,请你快速查找出该缩写对应的人名。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
struct Person{
char name[31];
}p[101];
int cmp(const void* e1,const void* e2){
struct Person* a = (struct Person*)e1;
struct Person* b = (struct Person*)e2;
//返回值为负,e1排在e2前面
return strcmp(a->name,b->name)<0?-1:1;
}
void check(char s[],int n){
int span = 'A' - 'a';
int i = 0;
for(i = 0;i<strlen(s);i++){
s[i]+=span;
}
int c = 0;
//注意!strlen遇到空格不会停止读取!
for(i = 0;i<n;i++){
char name[31] = {0};
int count = 0;
for(int j = 0;j<strlen(p[i].name);j++){
if(p[i].name[j]>='A'&&p[i].name[j]<='Z'){
name[count++] = p[i].name[j];
}
}
if(strcmp(s,name)==0){
puts(p[i].name);
c = 1;
}
}
if(c==0){
printf("No");
}
}
int main(){
int n = 0;
scanf("%d\n",&n);
for(int i = 0;i<n;i++){
gets(p[i].name);
}
char goal[31] = {0};
gets(goal);
qsort(p,n,sizeof(struct Person),cmp);
check(goal,n);
return 0;
}
【程序5】碧蓝航线
《碧蓝航线》是时下非常热门的一款游戏,是b站代理第二的游戏(第一FGO)。
《碧蓝航线》里面有一个演习模式,这个模式出击需要六艘战舰,前排3艘(前排战舰类型为DD(驱逐),CA(重巡),CL(轻巡)),后排3艘(后排战舰类型BB(战列),CV(航母))。每艘船都有战斗力,一般情况下总战斗力(六艘战斗力的和)和越大,演习的胜率越高。
因为前一段时间海军节,kirito迷上了《碧蓝航线》,他想最大可能性赢得演习的条件下,按阵营喜欢程度上阵战舰(总共4个阵营,白鹰、铁血、重樱、皇家),请你帮他选出6艘战舰,输出总战力和六艘战舰名字,若不行则输出NO。
【样例1】 10 2 3 4 1 Enterprise 4000 CV 1 Nagato 4500 BB 3 Azuma 4200 CA 3 Hood 3800 BB 4 Eldridge 3900 DD 1 Yuudachi 3500 DD 3 Kaga 4000 CV 3 Akagi 4000 CV 3 PrinzEugen 4000 CA 2 Z46 3900 DD 2 【样例2】 6 1 2 3 4 22 9999 DD 1 33 9999 DD 4 Asuna 8888 CL 3 Minneapolis 8888 CA 1 Yamato 7777 BB 3 Musashi 7777 BB 3
【样例1】 24600 Azuma PrinzEugen Z46 Nagato Kaga Akagi 【样例2】 NO
第二个样例后排无法组成,所以为NO
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
struct Ship {
char name[21];
int atk;//攻击
char type[3];
//前排:DD,CA,CL
//后排:BB,CV
int camp[1][2];//1白鹰,2铁血,3重樱,4皇家
//第一列是阵营,第二列是喜爱程度
}ship[101],f[101],b[101];
int sum_atk = 0;
void Print() {
int i = 0;
printf("%d\n", sum_atk);
for (i = 0; i < 3; i++) {
printf("%s\n", f[i].name);
}
for (i = 0; i < 3; i++) {
printf("%s\n", b[i].name);
}
}
int cmp(const void* e1, const void* e2) {
struct Ship* a = (struct Ship*)e1;
struct Ship* b = (struct Ship*)e2;
if(a->atk != b->atk){
return b->atk - a->atk;
}
if(a->camp[0][1] != b->camp[0][1]){
return b->camp[0][1] - a->camp[0][1];
}
return strcmp(a->name,b->name)>0?-1:1;
}
int main() {
int n = 0;
scanf("%d", &n);
if (n < 6) {
printf("NO");
return 0;
}
int front = 0, behind = 0;
int i = 0, j = 0;
int keen[4] = { 0 };//喜爱程度 ,1白鹰,2铁血,3重樱,4皇家
for (i = 0; i < 4; i++) {
scanf("%d", &keen[i]);
}
for (i = 0; i < n; i++) {
scanf("%s %d %s %d\n", ship[i].name, &ship[i].atk, ship[i].type, &ship[i].camp[0][0]);
//getchar();
ship[i].camp[0][1] = keen[ship[i].camp[0][0] - 1];
if (strcmp(ship[i].type, "DD") == 0 || strcmp(ship[i].type, "CA") == 0 || strcmp(ship[i].type, "CL") == 0) {
f[front] = ship[i];
front++;
}
else {
b[behind] = ship[i];
behind++;
}
}
if (front < 3 || behind < 3) {
printf("NO");
return 0;
}
qsort(f, front, sizeof(struct Ship), cmp);
qsort(b, front, sizeof(struct Ship), cmp);
for (i = 0; i < 3; i++) {
sum_atk += f[i].atk;
sum_atk += b[i].atk;
}
Print();
return 0;
}
【程序6】转义字符
1.打印 '\',要用 \\
2.打印 “ 或 " ,要用 \"
3.打印 %,要用 %%
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
int main() {
char a;
scanf("%c",&a);
printf("#include<stdio.h>\n");
printf("int main()\n");
printf("{\n");
printf(" printf(\"%%c\\n\",'\\x%X');\n",a);
printf("}\n");
return 0;
}
【程序7】高效递归求组合数
int dfs(int m, int n) {
if (m == 0 || n == 0 || m == n) {
return 1;
}
if (n > m / 2) {
n = m - n;
}
return dfs(m - 1, n - 1) * m / n;
}
【程序7】计算分子量
题目描述
已知氢的原子量为1,碳的原子量为12,氧的原子量为16,输入化学结构式/分子式,计算对应的分子量
例如:乙酸(醋酸)的分子式为CH3COOH,分子量为12+1×3+12+16+16+1=60
输入
分子式/结构式,长度不超过30,在分子式/结构式中只有字母和数字,
其中的字母只会出现三个大写字母CHO,另外在数值之前必然有字母。
测试数据有多组,处理到输入结束。
输出
输出分子量(正整数),每个输出占1行。
样例输入
H2
C
O2
CO2
H2O
CH4
CH3CH2OH
CH3COOH
CH3COOCH2CH3
C4H10
C12H22O11
样例输出
2
12
32
44
18
16
46
60
88
58
342
双指针
int check(char a,int n){
if(n==0){
n=1;
}
if(a == 'H'){
return 1*n;
}
if(a=='C'){
return 12*n;
}
if(a=='O'){
return 16*n;
}
return 0;
}
int Calc(char* s){
int sum = 0;
int n = 0;
int i = 0;
char* fast = s+1;
char* slow = s;
int span = '1' - 1;
while(*slow){
char num[5] = {0};
i= 0;
n = 0;
while(*fast>='0'&&*fast<='9'){
num[i++] = *fast;
fast++;
}
for(int j = i-1;j>=0;j--){
n+=(num[i-j-1]-span)*pow(10,j);
}
sum+=check(*slow,n);
slow = fast;
fast = slow + 1;
}
return sum;
}
int main()
{
char s[33] = {0};//试试gets
while(scanf("%s",s)!=EOF){
printf("%d\n",Calc(s));
}
return 0;
}