目录

A.爱因斯坦光电效应

B.图书馆信息管理系统

C.这年头难道有人不喜欢签到吗

D.lsjp和他的小伙伴们

E.lwjq与国际象棋

F.lzlf的三角形绝技

G.lwyj的最短路径

H.cgg学长的致富之路

A.爱因斯坦光电效应

    思路:本题给出五个用字符串表示的时间段,需要分别对五个时间段进行处理然后算出五个时间段用秒表示的时间然后存储一下五个时间段的值,之后再循环模拟出所有情况的答案看是否有匹配的答案就可以了,如果有输出Yes,如果没有符合的就输出No。

#include<stdio.h>
int v[30], a, b, c, x, y, z;
int main()
{for (int i = 1; i <= 5; i++) //存储每个时间段用秒表示的总时间{scanf("%d:%d:%d %d:%d:%d", &a, &b, &c, &x, &y, &z);int start, end;end = x * 3600 + y * 60 + z;start = a * 3600 + b * 60 + c;v[i] = end - start;}int ans, f = 0;scanf("%d", &ans);for (int i = 0; i <= 1; i++)       //判断第一个时间段选不选{for (int j = 0; j <= 1; j++)    //判断第二个时间段选不选{for (int k = 0; k <= 1; k++)  //判断第三个时间段选不选{for (int q = 0; q <= 1; q++) //判断第四个时间段选不选{for (int w = 0; w <= 1; w++) //判断第五个时间段选不选{int res = 0;if (i == 1) res += v[1];if (j == 1) res += v[2];if (k == 1) res += v[3];if (q == 1) res += v[4];if (w == 1) res += v[5];if (res == ans)    //有符合的方案{f = 1; printf("Yes\n"); return 0;}}}}}}if (!f) printf("No\n");  //没有符合的方案
}

B.图书馆信息管理系统

思路:这道题目的意思是要判断第一行的字符串能不能通过删除一些子串得到第二个字符串,本质理论是判断第二个字符串的所有元素是否可以按顺序出现在第一个串中即可。

具体实现:循环+双指针维持即可。参考代码如下:

#include<stdio.h>
#include<string.h>
char a[30], b[30];
int main()
{gets(a);gets(b);if (strlen(b) > strlen(a))     //b的长度比a的长直接输出NO{puts("NO"); return 0;      }else{int j = 0;for (int i = 0;i < strlen(a);i++)    //判断b字符串中的字符是否按顺序出现在a中{if (a[i] == b[j]){j++;}}if (j == strlen(b))    //符合{puts("YES");}else                  //不符合{puts("NO");}}
}

C.这年头难道有人不喜欢签到吗

题意分析:这道题相当于是数字组合的问题,数字范围是1e9,那么我们可以先把该范围的所有符合的数字先提前预处理存一下,方便程序的实现。

具体分析:接下来的实现就是得到一个正整数n,首先先加上比n的位数少的符合的数字的个数,然后再对n所在的位数符合的数字进行判断,判断该问题时,我们可以从头往后处理,模拟处理。

#include<stdio.h>
#include<string.h>
#include<math.h>
char a[20];
int v[100];
signed main()
{int sum = 9;       //数据范围最大1e9;int x = 1, xx = 0;while (sum--)      //预处理存储相应位数数字的所有可能的情况{v[xx++] = x; x *= 2;}gets(a);int pd = a[0] - '0';if (pd > 1)              //首位数字大于1的时候则可以生成该位数所有的情况{int ans = 0;for (int i = 0;i < strlen(a);i++){ans += v[i];}printf("%d\n", ans);}else                    //首位数字等于1{int ans = 0;for (int i = 0;i < strlen(a) - 1;i++)   //生成比该数字位数少1的所有情况{ans += v[i];}int flag = -1, xx, pd = 0;for (int i = 1;i < strlen(a);i++)       //从第一位数字开始处理当前位数的数字{xx = a[i] - '0';if (xx > 1)             //若处理位大于1则后续数字均可以由0或1代替,排列组合思想,总情况就是pow(2, strlen(a) - i){pd = 1;ans += pow(2, strlen(a) - i); flag = 1; break;}else if (xx == 1)      //若处理位等于1则当前位不能替换但后续位的数字可以替换为0或1,总情况就是 pow(2, strlen(a) - i - 1){ans += pow(2, strlen(a) - i - 1); flag = 1;}}if (flag == -1 || !pd)  //特判输入数字第一位是1需要加上它本身;  特判输入数字为0{ans++;}printf("%d\n", ans);}
}

lcl大佬的暴力代码:

#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
signed main()
{ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);int t = 1;while (t--){int n;cin >> n;int ans = 0;for (int i = 1; i <= n; i+=10)   //暴力判断以1为最后一位的数中符合条件的数量{int x = i;int ok = 1;while(x&&ok){if(x%10>1)ok = 0;x /= 10;}ans += ok;}for (int i = 10; i <= n; i+=10) //暴力判断以0为最后一位的数中符合条件的数量{int x = i;int ok = 1;while(x&&ok){if(x%10>1)ok = 0;x /= 10;}ans += ok;}cout << ans << endl;}
}

sjp大佬写法,采用位运算(感兴趣的了解):

#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
using namespace std;
const int N = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9;
int n, ans;
int main()
{ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);cin >> n;if(n==1e9) ans++;   //等于1e9时的特判for (int i = 1; i < (1 << 9); i++)  //计算一共2的9次方{int k = 0;for (int j = 0; j < 9; j++)       //将二进制转成十进制数k = k * 10 + ((i >> j) & 1);if (k <= n) ans++;    //判断该数字与n的大小关系}cout << ans;return 0;
}

哲佬的数位dp(感兴趣的了解):

#include <bits/stdc++.h>
using namespace std;int n;
int dp[15],a[15];int dfs(int pos,bool limit)
{if(pos==0) return 1;if(!limit&&dp[pos]!=-1) return dp[pos];int binary=limit?min(a[pos],1):1,cnt=0;for(int i=0;i<=binary;i++){cnt+=dfs(pos-1,limit&&i==a[pos]);}if(!limit) dp[pos]=cnt;return cnt;
}int solve(int x)
{int pos=0;while(x){a[++pos]=x%10;x/=10;}return dfs(pos,true);
}int main()
{memset(dp,-1,sizeof(dp));scanf("%d",&n);printf("%d\n",solve(n)-1);return 0;
}

D.lsjp和他的小伙伴们

题意理解:这道题目主要就是概率和最大公约数的相关知识点,只要找出大于等于前两位点数的情况再约分即可。

#include<stdio.h>
int gcd(int x, int y)         //最大公约数用于约分
{if (x%y == 0) return y;else return gcd(y, x%y);
}
int main()
{int a, b; scanf("%d %d", &a, &b);int maxx = a > b ? a : b;   //求a,b中的最大的那个int ans = 6 - maxx + 1;int x = gcd(ans, 6);printf("%d/%d\n", ans / x, 6 / x);
}

E.lwjq与国际象棋

 思路:先理解下题意,这道题同样是给了一个类似于棋盘的模型,但该棋盘是8*8限定棋盘,每次操作是可以让一行全变为黑色,或者让一列全变为黑色,最终让统计所做的操作数。那么既然每次可以影响一行或者一列,那么我们只需判断第一行的元素和判断第一列的元素即可。

具体分析:也就是我们分别判断第一行的每个元素,判断的实现是判断该元素所在的列是否全染色,同样分别判断第一列的每个元素的时候的实现也是同样的思路。但要注意的是要特判一下整个棋牌都被染成黑色的情况,不然上述的模拟会多加答案的数目。ok,分析完这些直接上代码:

#include<stdio.h>
char a[10][10];
int main()
{int pd = 1;for (int i = 1;i <= 8;i++){for (int j = 1;j <= 8;j++){scanf(" %c", &a[i][j]);if (a[i][j] != 'B'){pd = 0;}}}if (pd)        //判断所有字符全为B{printf("8"); return 0;}int ans = 0;for (int j = 1;j <= 8;j++) {if (a[1][j] == 'B')//判断第一行字符如果有B则判断该B所在的列{int pd = 1;for (int k = 1;k <= 8;k++){if (a[k][j] != 'B')      //有不符合的情况{pd = 0; break;}}if (pd) ans++;}}for (int i = 1;i <= 8;i++){if (a[i][1] == 'B') //判断第一列字符如果有B则判断该B所在的行{int pd = 1;for (int k = 1;k <= 8;k++){if (a[i][k] != 'B')   //有不符合的情况{pd = 0; break;}}if (pd) ans++;}}printf("%d\n", ans);
}

F.lzlf的三角形绝技

思路:这道题目给出了退化三角形的定义,也就是一个角度是180度或者两个角度都是90度,面积为0的三角形,关于角度的处理是不太方便的,那么我们可以进行转化,也就是说,一个角度是180度意思是有两边之和等于第三边,相当于是等腰三角形腰边和底边重合了,两个角度都是90度的可以转化为有一条边是0;有了这个思路之后我们就可以按照题目给的数据进行判断了。参考代码如下:

#include<stdio.h>
int main()
{int a, b, c, d;scanf("%d %d %d %d", &a, &b, &c, &d);int sum = 0; //判断有多少个0if (a == 0) sum++;if (b == 0) sum++;if (c == 0) sum++;if (d == 0) sum++;if ((a + b > c) && (a + c > b) && (b + c > a) || (a + b > d) && (a + d > b) && (b + d > a) || (a + c > d) && (a + d > c) && (c + d > a) || (b + c > d) && (b + d > c) && (c + d > b)){puts("TRIANGLE"); //判断可以组成三角形}else if (((a + b == c) || (a + c == b) || (b + c == a) || (a + b == d) || (a + d == b) || (b + d == a) || (a + c == d) || (a + d == c) || (c + d == a) || (b + c == d) || (b + d == c) || (c + d == b)) || (sum > 0 && sum <= 2)){puts("SEGMENT"); //判断可以组成退化三角形:两边相加等于第三边或有0边}else{puts("IMPOSSIBLE");}
}

G.lwyj的最短路径

思路:本题采用贪心的思想,也就是说可以斜着走就斜着走,因为这样其实是一步走两个格子,当不能斜着走的时候再水平移动或者竖直移动。

具体分析:首先要明确一点,从起点到终点本质上的区别是竖直方向距离和水平方向距离的区别,那么走一步产生的影响有三种,水平方向间距减少1,竖直方向间距减少1,水平方向和竖直方向的间距同时减少1。那么很显然最少的操作数就是水平方向间距的差值和竖直方向间距的差值的最大值(由起点到终点的最理想状态),分析完了这个之后我们可以直接写代码了。

第一种写法:从起点到终点的横纵坐标的差值有四种情况(根据正负的组合即可得出有四种),那么我们可以分开讨论再模拟走的过程并输出相应的操作即可:

#include<stdio.h>
#include<math.h>
int main()
{char x; int y;char a; int b;scanf("%c%d %c%d", &x, &y, &a, &b);int ans1 = a - x, ans2 = b - y;   printf("%d\n", abs(ans1) > abs(ans2) ? abs(ans1) : abs(ans2));  //最短路径if (ans1 >= 0 && ans2 <= 0)   //需要往右下走{while (ans1 > 0 && ans2 < 0){ans1--; ans2++; puts("RD");}if (ans1 == 0){while (ans2 < 0){ans2++; puts("D");}}else if (ans2 == 0){while (ans1 > 0){ans1--; puts("R");}}}else if (ans1 >= 0 && ans2 >= 0)  //需要往右上走{while (ans1 > 0 && ans2 > 0){ans1--; ans2--; puts("RU");}if (ans1 == 0){while (ans2 > 0){ans2--; puts("U");}}else if (ans2 == 0){while (ans1 > 0){ans1--; puts("R");}}}else if (ans1 <= 0 && ans2 >= 0) //需要往左上走{while (ans1 < 0 && ans2>0){ans1++; ans2--; puts("LU");}if (ans1 == 0){while (ans2 > 0){ans2--; puts("U");}}else if (ans2 == 0){while (ans1 < 0){ans1++; puts("L");}}}else if (ans1 <= 0 && ans2 <= 0)  //需要往左下走{while (ans1 < 0 && ans2 < 0){ans1++; ans2++; puts("LD");}if (ans1 == 0){while (ans2 < 0){ans2++; puts("D");}}else if (ans2 == 0){while (ans1 < 0){ans1++; puts("L");}}}
}

下面附上sjp大佬写法:

#include<math.h>
#include<stdio.h>
int h, l, x, y;
char hh[2] = { 'D', 'U' }, ll[2] = { 'L', 'R' };
char a[2], b[2];
int max(int a, int b)
{if (a > b) return a;else return b;
}
int min(int a, int b)
{if (a < b) return a;else return b;
}
int main()
{scanf("%s", a);scanf("%s", b);l = b[0] - a[0]; h = b[1] - a[1];  //计算两个点横竖位的差值//通过位置差确定应该往哪个方向走x = h >= 0 ? 1 : 0;  //x对应hh数组中的方向字母序号y = l >= 0 ? 1 : 0;  //y对应ll数组中的方向字母序号h = abs(h); l = abs(l);printf("%d\n",max(h, l));   //走的总步数就是横竖方向差值的较大那个for (int i = 1; i <= min(h, l); i++)   //先斜着走printf("%c%c\n", ll[y], hh[x]);if (h > l)    //最后分类判断是横向和竖向哪个方向需要走更多步数{for (int i = 1; i <= h - l; i++)printf("%c\n", hh[x]);}else{for (int i = 1; i <= l - h; i++)printf("%c\n", ll[y]);}return 0;
}

H.cgg学长的致富之路

思路:这道题的要求已经比较明确了,就是找最优的财富方案所得到的财富的总数,需要特殊注意的一点就是袋子都是相同的,那么我们只需要用现有的袋子优先去装金钱多的袋子即可。

具体分析:对金库每个袋子里面金币数量进行一个降序排序再去判断就可以了。参考代码如下:

写法1 暴力模拟:

#include<stdio.h>
int n,m,ans,res,xh,a[25],b[25],v[25];
int main()
{int i,j=0;scanf("%lld%lld",&n,&m);for(i=1;i<=m;i++)scanf("%lld%lld",&a[i],&b[i]);res=n;while(res>0)   //背包没有空间了即可退出循环{int num=-1,mx=-1;   //找出当前还未被取走的最大值for(i=1;i<=m;i++){if(!v[i]&&b[i]>mx){mx=b[i];num=i;}}if(num==-1) break;   //如果还是-1说明所有物品已被取完,即可直接退出循环v[num]=1;    //将该物品标为已取if(res>a[num])    //将当前价值最大的物品放入背包{res-=a[num];ans+=a[num]*b[num];}else{ans+=res*b[num];res=0;}}printf("%lld",ans);return 0;
}

写法2:

#include<algorithm>
#include<iostream>
using namespace std;
typedef struct jg
{int first, second;
}ff;
ff a[50];
bool cmp(ff q, ff w)
{return q.second > w.second;
}
int main()
{int n, m, x, y;scanf("%d %d", &n, &m);for (int i = 1;i <= m;i++){scanf("%d %d", &a[i].first, &a[i].second);}sort(a + 1, a + m + 1, cmp);     //使用sortint ans = 0;for (int i = 1;i <= m;i++){if (n >= a[i].first){ans += a[i].first*a[i].second; n -= a[i].first;}else{ans += n * a[i].second; break;}}printf("%d\n", ans);
}

2021HAUT第五周新生赛题解相关推荐

  1. 2015GPNU新生赛题解

    2015GPNU新生赛题解 今年的题目结合了往年的题目和华工,华师新生赛题目,确实是历年最难. * 1001 * Problem Description 最近ACM协会各种各样的费用都要申报,会长一时 ...

  2. 2019年安徽大学ACM/ICPC实验室新生赛题解

    本文仅作个人收藏学习使用 题目及解析来源牛客竞赛网 //作者:王清楚 //链接:https://ac.nowcoder.com/discuss/351408?type=101&order=0& ...

  3. 2016中北大学ACM程序设计新生赛题解

    新生赛题目地址 a or an 输入字符串后判断第一个字符是不是'a','e','i','o','u',即可. #include<algorithm> #include <iostr ...

  4. 2021暨南大学轩辕杯ACM程序设计新生赛题解

    title : 2021暨南大学轩辕杯ACM程序设计新生赛 date : 2021-12-12 tags : ACM,练习记录 author : Linno 题目链接:https://ac.nowco ...

  5. [炉石]2017杭州第五周实力赛记录

    这周22号是炉石传说实力赛第五周的比赛.17年的实力赛我一共报了三场,前一场因为忙着申请实习错过了,原本把本周的比赛也忘记了,多亏在21号早上室友无意间提了一句"你之前报的实力赛的怎么还没打 ...

  6. 2019四川大学第二届SCUACM新生赛题解

    解题后记: 1.题是好题,虽然简单,都是学习C语言程序设计必学的内容. 2.通用化编程往往没有得到重视,尤其是初学的时候. 3.结构化程序设计非常重要,需要从开始就把握. 4.代码不仅要简洁,而且要极 ...

  7. 2021年浙江工商大学新生赛题解

    本篇中的题目顺序为预期难度顺序,并非比赛题目顺序 本篇中所有的"更好的优化"均为标准答案之外的思考,不使用此内容也可以通过题目 本文为拷贝版本,可能存在图片丢失等问题,不修复,请前 ...

  8. 2022济南大学acm新生赛题解

    通过答题情况的难度系数: 签到:ABL 简单:DGKQ 中等:CMN 困难:EFHIJOPRST A-和 算出n个数的和判断正负性即可!!! 发现很多同学的代码错误:要么sum未赋初值,要么数组大小定 ...

  9. 2017网络新生赛题解

    硬币翻转 题目描述 在桌面上有一排硬币,共N枚,每一枚硬币均为正面朝上.现在要把所有的硬币翻转成反面朝上,规则是每次可翻转任意N-1枚硬币(正面向上的被翻转为反面向上,反之亦然).求一个最短的操作序列 ...

最新文章

  1. Twitter团队最新研究:快速高效的可扩展图神经网络SIGN
  2. 如何理解Return的返回值?
  3. sql server数据库查询超时报错
  4. vs2008C1902程序数据库管理不匹配
  5. linux c语言 udp 接收和发送数据用同一个端口_网络编程基础入门及TCP,UDP
  6. Linux系统可卸载内核模块完全指南(上)
  7. 数据库表存放在哪里_一文了解数据库和数据仓库
  8. 读书笔记--对象、实例、原型、继承 1
  9. 项目集成sentry
  10. php中strtotime函数,PHP中strtotime函数用法举例
  11. matlab矩阵转置函数
  12. 解决jy61陀螺仪传感器读数跳动的问题
  13. 网站/APP 流量分析、点击流分析、用户访问分析
  14. GIS地理信息定位系统
  15. opencv 中x,y,height, width,rows,cols 的关系
  16. 基于php的网络教学平台,基于PHP技术的网络教学平台的设计与实现
  17. matlab怎么测脉络膜血管密度,【CCOS2016】OCT血管成像的发展之路
  18. 数值分析中对有效数字的定义
  19. 源码交易平台如何选择
  20. linux 为普通用户分配权限

热门文章

  1. Python实现简单的闹钟/倒计时/番茄钟软件并打包成exe
  2. 【导航】自己的导航网站
  3. 2022-2028全球汽车轮胎充气泵行业调研及趋势分析报告
  4. C盘临时文件怎么删除?
  5. 青龙面板之今日油条(更新)
  6. 华为鸿蒙,告别 PPT,代码全部开源!
  7. 腾讯云Coding平台入门指引
  8. 朴素贝叶斯分类算法--终极奥义
  9. 给button按钮绑定Enter回车键
  10. System.Data.SqlClient.SqlException:“在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 S