组合技
此题将n-1个元素加1可以等价于
每次让1个元素-1,多少次后所有元素相等
#include <stdio.h>
int main() {
int t, n;
int num[1010];
scanf("%d", &t);
for (int i = 1; i <= t; i++) {
scanf("%d", &n);
int sum = 0;
int min = 100;
for (int j = 0; j < n; j++) {
scanf("%d", &num[j]);
sum += num[j];
if (min > num[j]) {
min = num[j];
}
}
printf("Case #%d:\n%d\n", i, sum - min * n);
}
}
站好队
简单dfs
题意为把k个学生放到方形队伍中,这些学生不能同一行也不能同一列,问有多少种结果
具体可看注释
#include<stdio.h>
#include<string.h>
//把cb,cbc,ans,n,k弄成全局变量,方便在dfs中使用
char cb[100][100];
int cbc[100];
long long ans = 0;
int n, k;
void dfs(int x, int y)//x是行数,y是学生数
{
if (k == y) {//当学生数达到要求时
ans++;
return;
}
for (int i = x; i < n; i++) {
//因为题目要求不能同一行,所以从x开始往下扫描
for (int j = 0; j < n; j++) {
//不能同一列,用数组cbc来存结果
if (cb[i][j] == '#' && cbc[j] == 0) {
//如果有过了这一列了,就用让cbc=1,等到这次递归完成,再改回0
cbc[j] = 1;
dfs(i + 1, y + 1);
cbc[j] = 0;
}
}
}
}
int main() {
int t;
scanf("%d", &t);
for (int q = 1; q <= t; q++) {
scanf("%d %d", &n, &k);
memset(cbc, 0, sizeof(cbc));//使数组全部为0
getchar();
for (int i = 0; i < n; i++) {
gets(cb[i]);
}
ans = 0;
dfs(0, 0);
printf("Case #%d:\n%lld\n", q, ans);
}
}
我不看月亮
就是看摸鱼和放回鱼的数量,如果已经到了0就不减
代码:
#include<stdio.h>
#include<string.h>
int main() {
int t, n;
char cb[1000000];
int ans[101];
memset(ans, 0, sizeof(ans));
scanf("%d", &t);
for (int i = 1; i <= t; i++) {
scanf("%d", &n);
scanf("%s", cb + 1);
for (int j = 1; j <= n; j++) {
if (cb[j] == 'c') {
if (ans[i] > 0) {
ans[i]--;
}
} else {
ans[i]++;
}
}
}
for (int i = 1; i <= t; i++) {
printf("Case #%d:\n%lld\n", i, ans[i]);
}
}
记忆大王李华
#include<stdio.h>
#include<stdlib.h>
//该公式中把一月和二月看成是上一年的十三月和十四月
int main(void)
{
int year, month, day;
int d1[13] = {31,28,31,30,31,30,31,31,30,31,30,31};
int d2[13] = {31,29,31,30,31,30,31,31,30,31,30,31};
int cas = 1;
while(~scanf("%d %d %d", &year, &month, &day)){
getchar();
int sum = 0;
if((year<=0 || year>=10000)||(month<=0 || month>=13)||(day<=0||day>=32)){
continue;
}
if((year%100!=0 && year%4==0)||year%400==0){
for(int i = 0; i < month-1; i++){
sum += d2[i];
}
}
else{
for(int i = 0; i < month-1; i++){
sum += d1[i];
}
}
sum+=day;
for(int i = 1; i < year; i++){
if((i%100!=0 && i%4==0)||i%400==0)
sum+=366;
else
sum+=365;
}
printf("Case #%d:\n",cas++);
int x = sum % 7;
switch(x){
case 0:
printf("Sunday\n");
break;
case 1:
printf("Monday\n");
break;
case 2:
printf("Tuesday\n");
break;
case 3:
printf("Wednesday\n");
break;
case 4:
printf("Thursday\n");
break;
case 5:
printf("Friday\n");
break;
case 6:
printf("Saturday\n");
break;
}
}
return 0;
}
小彩蛋
部分题目名的典故
后海有树的院子,夏代有工的玉,此时此刻的云,二十来岁的你。
为什么乌鸦像写字台——就像我喜欢你,没有理由
我不看月亮,也不说想你,这样月亮和你都蒙在鼓里
人们从诗人的字句里 选取自己心爱的意义 但诗句最终意义是指向你
我想要在茅亭里看雨、假山边看蚂蚁,看蝴蝶恋爱,看蜘蛛结网,看水,看船,看云,看瀑布,看宋清如甜甜地睡觉
世间情动,不过盛夏白瓷梅子汤,碎冰碰壁当啷响
要和你秉烛夜游,要和你一醉方休;
要与你听风轻雨柔,要与你游山清水秀;
要为你采了莲叶熬粥 要为你摘了桂花酿酒;
这一生,怎么够?
用来签到的打牌游戏
本题的重点是思路思路思路
无非就是摸牌摸起来升序。想象着有个摄像机拍摄你摸牌的过程:摸了一张,放了一张到末尾(牌堆底部),一直循环这个过程直到摸完。你手上有了一个升序的牌组
现在开始倒放步骤一提到的录像。画面显示:你从升序的牌组中拿了一个最大的(你在步骤一中最后放进牌组的牌),放到了桌上;把末尾的牌放到最开始的位置(牌堆顶),如果桌上没有牌或者只有一张牌则直接放牌。普遍的过程变成了:放一张到开始位置(牌堆顶部),放一张牌
converse函数是“放一张到顶部”,set是“从手上放一张牌下去”,排序后的desk数组就是手里的牌。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int Cmp(const void* a, const void* b)
{
return *(int*)a - *(int*)b;
}
void converse(int* ret, int q)
{
if (q == 0) {
return;
}
int temp = ret[q - 1];
for (int i = q - 1; i > 0; i--) {
ret[i] = ret[i - 1];
}
ret[0] = temp;
return;
}
void set(int* ret, int q, int tag)
{
for (int i = q - 1; i > 0; i--) {
ret[i] = ret[i - 1];
}
ret[0] = tag;
return;
}
int* deckRevealedIncreasing(int* deck, int deckSize)
{
qsort(deck, deckSize, sizeof(int), Cmp);
int* ret = (int*)malloc(deckSize * sizeof(int));
memset(ret, 0, deckSize * sizeof(int));
int q = 0;
for (int i = deckSize - 1; i >= 0; i--) {
converse(ret, q);
q++;
set(ret, q, deck[i]);
}
/**returnSize = q;*/
return ret;
}
int main() {
int n;
int a[1000000];
int* c;
int t;
while (~scanf("%d",&t)){
int j = 0;
for (int i = 0; i < t; i++) {
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
c = deckRevealedIncreasing(a, n);
j++;
printf("Case #%d:\n", j);
for (int i = 0; i < n; i++) {
if (i == n - 1)
printf("%d ", c[i]);
else
printf("%d ", c[i]);
}
printf("\n");
}
}
return 0;
}
你会看天气预报吗
暴力,直接遍历一遍,然后判断输出即可
#include<stdio.h>
#include<string.h>
int main()
{
int t;
int cb[1001];
scanf("%d",&t);
for(int i = 1; i <= t; i ++){
int n;
scanf("%d",&n);
for(int j=0 ; j<n ;j++){
scanf("%d",&cb[j]);
}
printf("Case #%d:\n",i);
for(int j=0; j<n ; j++){
for(int k=j ; k<n ; k++){
if(cb[j]<cb[k]){
printf("%d ",k-j);
break;
}
if(k==n-1){
printf("0 ");
}
}
}
printf("\n");
}
}
小明的派对
数量较少,直接暴力
想用一个数组存男生在L-R时间段里的人数(数组的数目表示今天能参加的男生数)
同理将女生的存起来
最后找到366天每一天男女参加人数的最小值的两倍,然后取出其中的最大值即可。
#include<stdio.h>
#include<string.h>
int cb[2][1000];
int min(int a,int b){
if(a<b)return a;
return b;
}
int main()
{
int t;
scanf("%d",&t);
for(int i = 1; i <= t; i ++){
memset(cb,0,sizeof(cb));
int n,a,b;
char sex;
scanf("%d",&n);
for(int j=1 ; j<=n ; j++){
getchar();
scanf("%c %d %d",&sex,&a,&b);
if(sex == 'M'){
for(int q=a ; q<=b ; q++){
cb[0][q]++;
}
}else{
for(int q=a ; q<=b ; q++){
cb[1][q]++;
}
}
}
int max = 0;
for(int j=1 ; j<=366 ; j++){
if(cb[0][j]&&cb[1][j]){
if(max<min(cb[0][j],cb[1][j])){
max = min(cb[0][j],cb[1][j]);
}
}
}
printf("Case #%d:\n%d\n",i,max*2);
}
}
茅亭里看雨 切西瓜
签到题
简单判断即可
#include<stdio.h>
int main(){
int t;
scanf("%d",&t);
for(int i=1 ; i<=t ; i++){
int w;
scanf("%d",&w);
printf("Case #%d:\n",i);
if(w==2)
printf("NO\n");
else{
if(w%2==0)
printf("YES\n");
else
printf("NO\n");
}
}
}
盛夏白瓷梅子汤
7和9,我们在1000内可以组成
9,7,97,99,77,79,999,997,977,777,779,799,979,797
数量不多,我们可以直接写出然后遍历即可
#include<stdio.h>
int main()
{
int i,n,flag=0;
int a[20]={9,7,97,99,77,79,999,997,977,777,779,799,979,797};
int t;
scanf("%d",&t);
for(int q=1 ; q<=t; q++){
scanf("%d",&n);
flag = 0;
for(i=0;i<14;i++)
{
if(n%a[i]==0)
flag=1;
}
printf("Case #%d:\n",q);
if(flag==1)
printf("Shmily\n");
else
printf("NoShmily\n");
}
}
秉烛夜游 一醉方休
先看m%n是否除的尽
可以的话,然后算出m是n的多少倍,然后倍数来不停除3,除2,每出一次步数ans++,如果最后的结构不等于1,就不满足,例如 n=1,m=5,满足的话,除完一定等于1.
#include<stdio.h>
int main() {
int t, n, m, cnt;
int step = 0;
scanf("%d", &t);
for (int i = 1; i <= t; ++i) {
step = 0;
scanf("%d%d", &n, &m);
printf("Case #%d:\n", i);
if (m % n != 0) {
printf("-1\n");
cnt = 1;
} else {
m = m / n;
cnt = 0;
while (m != 1) {
if (m % 2 == 0) {
step++;
m = m / 2;
continue;
}
if (m % 3 == 0) {
step++;
m = m / 3;
continue;
}
printf("-1\n");
cnt = 1;
break;
}
}
if (cnt == 0)
printf("%d\n", step);
}
}