河南工大2024新生周赛(4)——命题人:马贺
A:Doki Doki Literature Club!
直接输出就可以了。
#include<stdio.h> int main()
{ printf("Just Monika!"); return 0; }
B:君と彼女と彼女の恋
∵ y 最大可以等于 x
∴ gcd(x,y) 最大 = x
直接输出 2∗x 即可
#include<stdio.h> int main()
{ int x; scanf("%d",&x); printf("%d",x*2); return 0; }
C:Raging Loop
把特殊情况都考虑进去即可。 101 不是。
#include <stdio.h> int main() { char num[100]; scanf("%s", num); // 计算字符串长度 int length = 0; while (num[length] != 0) { length++; } if (length < 3) { printf("chi ga u\n"); } else { // 判断前两位是否为"10" if (num[0] == '1' && num[1] == '0') { int third_digit = num[2]- '0';
// 提取第三个字符作为数字 if (third_digit >= 2)
{ printf("Hai\n"); }
else if (third_digit == 0) { printf("chi ga u\n"); }
else { if (length > 3)
{ printf("Hai\n"); }
else { printf("chi ga u\n"); } } } else { printf("chi ga u\n"); } } return 0; }
D:Senren Banka
易推得 : 要么全部取偶数 , 要么全部取奇数。
故答案为 max(oddmax+oddsum,evenmax+evensum
#include<stdio.h> int max(int a,int b){ //返回两个数中的较大者 return a>b?a:b; } int main() { int arr[105]; int n ; scanf("%d",&n); int oddmax=0,evenmax=0; int oddsum=0,evensum=0; for (int i = 1; i <= n; ++i) { scanf("%d",&arr[i]); if (i%2==1){ oddmax= max(oddmax,arr[i]) ; oddsum++; }else{ evenmax= max(evenmax,arr[i]) ; evensum ++ ; } } printf("%d", max(oddmax+oddsum,evenmax+evensum)); return 0 ; }
E:Haut校草
注意到 , 要想得分最高 ,c 应该尽可能的大 , 而 b 应该尽可能的小。
故数组中的最大值和最小值一个放在第一 , 一个放在第二的时候 , 得分最高。
只需要把这两种情况都考虑一下 , 结果取二者最大值即可。
注意 , 无论哪种情况 , 总有 c1−b1=0, 故最后答案乘的是 (n−1)
#include <stdio.h> int main() { int n; scanf("%d", &n) ; int a[1005]; int max = 0, min = 1000000000; for (int i = 0; i < n; i++) { scanf("%d", &a[i]); if (i == 0) { min = a[i]; max = a[i]; } else { if (a[i] < min) { min = a[i]; } if (a[i] > max){ max = a[i] ; } } } printf("%d", (max - min) * (n - 1)) }
F:9nine~九次九日九重色
由于 n 范围较小 , 直接两重循环暴力即可。
给每个数做个标记 , 如果被标记为逆序对 , 就不是被孤立的数。
#include<stdio.h> int main(){ int t ; scanf(%d",&t) ; int num[1001] ; int ma = -1 ; for(int i = 1 ; i <= t ; ++ i ) { scanf("%d" , &num[i]) ; if(num[i] > ma) { ma = num[i] ; } } int reverse = 0 ; for(int i = 1 ; i < t ; ++ i){ for(int j = i + 1 ; j <= t ; ++ j) { if(num[j] < num[i] ) { reverse ++ ;//逆序对数量 } } } int glans = 0 ; //孤立的数的数量 for(int i = 1 ; i <= t ; ++ i ) { int flag = 1 ; for(int j = 1 ; j <= t ; ++ j ) { if( j == i ){ continue ; } else { if( j < i && num[j] > num[i] { flag = 0 ; break ; } if(j > i && num[j] < num[i] ) { flag = 0 ; break ; } } } if(flag) glans ++ ; } printf("%d %d\n" , reverse , glans) ; return 0 ; }
G:星空列车与白的旅行
易得 :
只有在 [n−k+1,n] 区间内增加的可爱值会持续存在到第 n 秒。
则问题转化为 :[n−k+1,n] 这一区间内总的可爱值加起来的奇偶性。
已知 : 偶数加偶数为偶数 , 奇数加奇数为偶数 , 偶数加奇数为奇数。 t t 的奇偶性与 t 有关 , 若 t 为奇数 , 则 tt 为奇数 , 反之为偶数。
问题进一步转化为 : 区间内奇数的个数和偶数的个数。
#include<stdio.h> int main(){ int n , k; scanf("%d %d ,&n , &k) ; if(k % 2 == 0) {//奇数和偶数的个数一样多 if((k / 2) % 2 == 0) { printf("YES") ;// 有偶数个奇数 }else{ printf("NO") ; } }else{ if((k - 1) / 2 % 2 == n % 2) printf("YES") ; else printf("NO") ; } return 0 ; }
H:NEEDY GIRL OVERDOSE
注意到如果分段数增加 , 最大值会减小 ; 反之最大值会增大。并且 , 对于一个最大值 , 如果对应的 段数小于要求的段数 , 那么比这个最大值还大的最大值对应段数一定也小于要求的段数。 对于这种满足单调性的答案 , 考虑二分。
每次选出来一个数作为预估的最大值 , 如果预估值对应的段数 ≤ 要求的段数 , 则这个预估答案是合理的 , 但不一定是最优的 , 需要考虑有没有更小的
#include<stdio.h> int max(int a , int b ) { return a > b ? a : b ; } int main(){ int n , k ; scanf("%d %d" , &n, &k) ; int num[100005] = {0} ; int rt = 0 ; int lt = 0 ; for(int i = 0 ; i < n ; ++ i){ scanf("%d" , &num[i + 1]) ; rt += num[i + 1] ;//答案最大的时候,一次吃完全部的药物 lt = max(lt , num[i + 1]) ;//答案最小也应该是所有药物中剂量最大的一篇 } while(lt < rt){ int mid = (lt + rt) / 2 ; int flag ; int segements = 1 ;//当前答案下分的段数 int sum = 0 ; for(int i = 1 ; i <= n ; ++ i){ if(sum + num[i] > mid) { segements ++ ; sum = 0 ; } sum += num[i] ; } if(segements > k) flag = 1 ; //说明这种分法不可行 需要的段数超过了要求 else flag = 0 ; if(flag) lt = mid + 1 ; else rt = mid ; } printf("%d" , lt) ; return 0 ; }