计算机学院第一周语法组及算法组作业
目录
语法组
费马定理
zhuzhu不会运算
期待已久的告白
Hello, ACM\
233
算法组
查找
石头剪刀布(生活大爆炸版)
不高兴的津津
进击的奶牛
寻找第一个大于等于
数字统计
数的范围
买铅笔
语法组
费马定理
题目描述
上了大学之后,小魏同学发现自己忘了很多中学的数学知识,比如说勾股定理,小魏同学写题发现有一题需要勾股定理解决,小魏同学因为没带脑子,翻找了一晚上的初中书籍,终于在凌晨四点钟在初中数学书上找到了这个公式,但是小魏同学实在是太困了,他有n道题需要解决,都是一类题,已知三角形三边长度a,b,c,请问能否构成直角三角形?
输入
第一行输入一个整数n(与题意相同)
接下来n行每行输入三个整数a,b,c(与题意相同)
输出
输出n行,如果a,b,c能构成直角三角形则输出YES,否则输出NO
样例输入
1
3 4 5
样例输出
YES
源代码
找寻符合勾股定理的三角形即可
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
while(n -- )
{
int a,b,c;
cin >> a >> b >> c;
int flag = 0;
if(a * a + b * b == c * c)flag = 1;
else if(a * a + c * c == b * b)flag = 1;
else if(b * b + c * c == a * a)flag = 1;
if(flag == 1)cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}
zhuzhu不会运算
题目描述
众所周知,zhuzhu很粗心,不会乘法,现在给你两个数
请你计算出乘法答案
输入
第一行一个数n表示输入样例个数
n行每行两个数形如:a b
输出
对于每组输入,输出一行一个整数表示结果
样例输入
2
1 2
2 3
样例输出
2
6
源代码
数据记得开long long,避免数据溢出
#include <iostream>
using namespace std;
typedef long long ll;
ll ans = 0,a,b;
int main()
{
int n;
cin >> n;
while(n -- )
{
cin >> a >> b;
ans = a * b;
cout << ans << endl;
}
return 0;
}
期待已久的告白
题目描述
ZY拥有着很多很多的好妹妹,他不想和这些好妹妹继续相处下去,春天到了,万物复苏,ZY的贤者模式突然解除了,他想从这些好妹妹当中挑选一个当女朋友,但是他是一个成年人了,小孩子才做选择,他想要全部都要,假设ZY表白之后好妹妹回复一串数字,那么根据数字进行判断,若是好妹妹扣了一个6,那么完蛋,ZY将会找ZYJ哭诉他的痛苦经历(QAQ)。若是好妹妹回复521,则ZY表白成功,十分欣喜((^o^)),若是好妹妹回复666,则ZY分不清好妹妹到底是同意还是没同意,将会回忆上了发条(emo),若是好妹妹回复的其他数字,那么ZY将会进入混乱状态(@A@)根据好妹妹的反应输出ZY的心情状况即可
输入
一个正整数n代表好妹妹的回复
输出
输出情况有三种:emo、QAQ、(^o^)、@A@
样例输入
6
样例输出
QAQ
源代码
简单的对应输出即可
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
if(n == 6)cout << "QAQ";
else if(n == 521)cout << "(^o^)";
else if(n == 666)cout << "emo";
else cout << "@A@";
return 0;
}
Hello, ACM\
题目描述
输出 "Hello, ACM\" (不含引号)
输入
无
输出
Hello, ACM\
源代码
考察转义字符的输出,加反斜杠即可
#include <iostream>
using namespace std;
int main()
{
string s = "Hello, ACM\\";
cout << s << endl;
return 0;
}
233
题目描述
233是一个网络用语,大致就是啊哈哈,非常好笑的意思
。233来源于猫扑表情第233号,是一张捶地大笑的表情,因此不少网友就喜爱在贴吧和论坛发帖的时候加上一句233,用来表示哈哈大笑的意思。同时“233”有时会演变为2333或者更多3跟在后边表示自己笑得很猖狂~多个3还可表示笑声持久,用来显示讽刺或表示内心欢喜。现在请你输出23333来表达自己心情愉悦。
输入
无
输出
23333
源代码
简单输出
#include <iostream>
using namespace std;
int main()
{
cout << "23333" << endl;
return 0;
}
算法组
查找
题目描述
输入
输出
样例输入
11 3
1 3 3 3 5 7 9 11 13 15 15
1 3 6
样例输出
1 2 -1
提示
源代码
注意数据点的输入过于巨大,所以对于巨量的数据输入输出,scanf和printf比cin和cout的速度快,建议用scanf和printf,当然cin和cout开了优化也可以过,不过还是速度略慢于scanf和printf,其次的考点就是一个二分用法
#include <iostream>
using namespace std;
const int N = 1000000 + 10;
int a[N];
int n,m;
int find(int x)
{
int l = 1,r = n;
while(l < r)
{
int mid = l + r >> 1;
if(a[mid] >= x)r = mid;
else l = mid + 1;
}
if(a[l] == x)return l;
else return -1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
for(int i = 1;i <= n;i ++ )cin >> a[i];
while(m -- )
{
int num;
cin >> num;
cout << find(num) << ' ';
}
return 0;
}
石头剪刀布(生活大爆炸版)
题目描述
输入
输出
样例输入
10 5 6
0 1 2 3 4
0 3 4 2 1 0
样例输出
6 2
提示
源代码
很简单的一道模拟题,注意对于二维表格只有j >= i的时候才会有输赢的结果出现,但是我们所用的数据里面给出的两个点可能会使j < i从而导致答案漏掉计算的情况出现,本题解使用flag打标记来实现将j < i转换为j >= i且满足输赢成果的转换
#include <iostream>
using namespace std;
const int N = 1000000 + 10;
int a[N],b[N];
int n,na,nb;
int ans1 = 0,ans2 = 0;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> na >> nb;
for(int i = 0;i < na;i ++ )cin >> a[i];
for(int i = 0;i < nb;i ++ )cin >> b[i];
for(int i = 0;i < n;i ++ )
{
int A = a[i % na],B = b[i % nb],flag = 1;
if(A > B)
{
swap(A,B);
flag = 0;
}
if(A == 0)
{
if(flag == 1)
{
if(B == 1)ans2 ++ ;
else if(B == 2)ans1 ++ ;
else if(B == 3)ans1 ++ ;
else if(B == 4)ans2 ++ ;
}
else if(flag == 0)
{
if(B == 1)ans1 ++ ;
else if(B == 2)ans2 ++ ;
else if(B == 3)ans2 ++ ;
else if(B == 4)ans1 ++ ;
}
}
else if(A == 1)
{
if(flag == 1)
{
if(B == 2)ans2 ++ ;
else if(B == 3)ans1 ++ ;
else if(B == 4)ans2 ++ ;
}
else if(flag == 0)
{
if(B == 2)ans1 ++ ;
else if(B == 3)ans2 ++ ;
else if(B == 4)ans1 ++ ;
}
}
else if(A == 2)
{
if(flag == 1)
{
if(B == 3)ans2 ++ ;
else if(B == 4)ans1 ++ ;
}
else if(flag == 0)
{
if(B == 3)ans1 ++ ;
else if(B == 4)ans2 ++ ;
}
}
else if(A == 3)
{
if(flag == 1)
{
if(B == 4)ans1 ++ ;
}
else if(flag == 0)
{
if(B == 4)ans2 ++ ;
}
}
}
cout << ans1 << ' ' << ans2 << endl;
return 0;
}
不高兴的津津
题目描述
妈妈认为津津应该更加用功学习,所以津津除了上学之外,还要参加妈妈为她报名的各科复习班。
另外每周妈妈还会送她去学习朗诵、舞蹈和钢琴。
但是津津如果一天上课超过八个小时就会不高兴,而且上得越久就会越不高兴。
假设津津不会因为其它事不高兴,并且她的不高兴不会持续到第二天。
请你帮忙检查一下津津下周的日程安排,看看下周她会不会不高兴;如果会的话,哪天最不高兴。
输入
输入文件包括七行数据,分别表示周一到周日的日程安排。
每行包括两个小于 10 的非负整数,用空格隔开,分别表示津津在学校上课的时间和妈妈安排她上课的时间。
输出
输出文件包括一行,这一行只包含一个数字。
如果不会不高兴则输出 0,如果会则输出最不高兴的是周几(用 1, 2, 3, 4, 5, 6, 7 分别表示周一,周二,周三,周四,周五,周六,周日)。
如果有两天或两天以上不高兴的程度相当,则输出时间最靠前的一天。
样例输入
5 3
6 2
7 2
5 3
5 4
0 4
0 6
样例输出
3
源代码
注意:若七天之中任意一天的补习时长都没有超过8,那么津津则每天都会很开心并没有不高兴,否则再从周一查至周日找出那儿天最不开心,从而同时完成优先天数靠前的输出
#include <iostream>
#include <vector>
using namespace std;
vector<int> A;
int main()
{
int ans = 0;
for(int i = 1;i <= 7;i ++ )
{
int a,b;
cin >> a >> b;
A.push_back(a + b);
ans = max(ans,a + b);
}
if(ans < 8)
{
cout << 0 << endl;
return 0;
}
for(int i = 0;i < A.size();i ++ )
{
if(ans == A[i])
{
cout << i + 1 << endl;
return 0;
}
}
return 0;
}
进击的奶牛
题目描述
Farmer John 建造了一个有 N(2 ≤ N ≤ 100000) 个隔间的牛棚,这些隔间分布在一条直线上,坐标是 (x1,...,xN(0<=xi<1000000000))
他的 C(x<=C<=N) 头牛不满于隔间的位置分布,它们为牛棚里其他的牛的存在而愤怒。为了防止牛之间的互相打斗,Farmer John 想把这些牛安置在指定的隔间,所有牛中相邻两头的最近距离越大越好。那么,这个最大的最近距离是多少呢?
输入
第 1 行:两个用空格隔开的数字 N 和 C。
第 2 ~ N+1 行:每行一个整数,表示每个隔间的坐标。
输出
输出只有一行,即相邻两头牛最大的最近距离。
样例输入
5 3
1
2
8
4
9
样例输出
3
源代码
实质即为从n个数当中取c个数构成一个升序序列,且前后二者之差最大化即可,首先进行check函数的设计,我们在main函数之中首先将数组进行升序排序,而后check函数操作的对象即为排序好的升序数组,那么首位肯定是a[0],其次我们还需要从中选取(n - c)个数,开始对于数组进行遍历,若遇见满足条件的数,则更新左端点,否则num计数器加一,已知,我们总共有着n个栅栏,那么排序后的头栅栏一定是确定了的,所以我们还需要从(n - 1)个栅栏当中选取(n - c)个栅栏,所以我们的栅栏总数为选取栅栏数c加上未选取的(n - c)个栅栏,也就是n个栅栏,那么在我们的check函数当中,原理即为若是不满足计数器加一,否则更新左端点。也就是说,计数器num计算的是未被选择的栅栏数,也即是盈余的栅栏数,若是此种情况成立,则盈余的栅栏数应该是等于need的,若其大于need,证明x的值过大,要缩小其值。那么对于main函数当中二分的设计,二分的左端点则是0,右端点即为a[n - 1] - a[0](x的最大值),而后不断二分即可,根据check函数的设计,当check函数返回true的时候,要么是恰好满足,要么则是x过于小,此时既要增大x,即左端点更新即可,注意在二分对于左端点更新的时候要避免进入死循环,否则TLE。而后若是check返回false的话,则x的值过大,逐渐缩小区间即可,直至二分找到最适合的x的值(利用check函数)
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1000000 + 10;
int a[N];
int n,c,need;
bool check(int x)
{
int num = 0;
int l = a[0];
for(int i = 1;i < n;i ++ )
{
if(a[i] - l >= x)l = a[i];
else num ++;
if(num > need)return false;
}
return true;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> c;
for(int i = 0;i < n;i ++ )cin >> a[i];
sort(a,a + n);
need = n - c;
int l = 0,r = a[n - 1] - a[0];
while(l < r)
{
int mid = l + r + 1 >> 1;
if(check(mid))l = mid;
else r = mid - 1;
}
cout << l << endl;
return 0;
}
寻找第一个大于等于
题目描述
给定你一个长度为n的有序序列,请使用二分法寻找第一个大于等于x的数的位置
输入
第一行包括两个正数n和x
第二行包括一行长度为n的有序序列
1≤n≤1e5
输出
如果存在大于等于x的数,则输出这个数的位置和数值,否则输出-1
样例输入
5 3
1 2 3 4 5
样例输出 复制
3 3
提示
有序序列的下标从1开始
源代码
简单二分模板题
#include <iostream>
using namespace std;
const int N = 1000000 + 10;
int a[N];
int n,m;
int find(int x)
{
int l = 1,r = n;
while(l < r)
{
int mid = l + r >> 1;
if(a[mid] >= x)r = mid;
else l = mid + 1;
}
if(a[l] >= x)return l;
else return -1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
for(int i = 1;i <= n;i ++ )cin >> a[i];
if(find(m) != -1)cout << find(m) << ' ' << a[find(m)] << endl;
else cout << -1 << endl;
return 0;
}
数字统计
题目描述
请统计某个给定范围 [L,R]的所有整数中,数字 2 出现的次数。
比如给定范围 [2,22],数字 2 在数 2 中出现了 1 次,在数 12 中出现 1 次,在数 20 中出现 1 次,在数 21 中出现 1 次,在数 22 中出现 2 次,所以数字 2 在该范围内一共出现了 6 次。
输入
输入共 1 行,为两个正整数 L和 R,之间用一个空格隔开。
-10000≤L≤R≤10000
输出
输出共 1 行,表示数字 2 出现的次数。
样例输入
2 22
样例输出
6
源代码
利用函数计算各个位数的2即可,氵题
#include <iostream>
using namespace std;
int get(int n)
{
int ans = 0;
if(n < 0)n = - n;
while(n > 0)
{
int num = n % 10;
if(num == 2)ans ++ ;
n /= 10;
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int l,r;
cin >> l >> r;
int ans = 0;
for(int i = l;i <= r;i ++ )ans += get(i);
cout << ans << endl;
return 0;
}
数的范围
题目描述
给定一个按照升序排列的长度为 n 的整数数组,以及 q 个查询。
对于每个查询,返回一个元素 k 的起始位置和终止位置(位置从 0 开始计数)。
如果数组中不存在该元素,则返回 -1。
输入
第一行包含整数 n 和 q,表示数组长度和询问个数。
第二行包含 n 个整数(均在 1∼10000 范围内),表示完整数组。
接下来 q 行,每行包含一个整数 k,表示一个询问元素。
输出
共 q 行,每行包含两个整数,表示所求元素的起始位置和终止位置。
如果数组中不存在该元素,则返回 -1。
样例输入
6 3
1 2 2 3 3 4
3
4
5
样例输出
3 4
5 5
-1 -1
提示
源代码
简单二分
#include <iostream>
using namespace std;
const int N = 1000000 + 10;
int a[N];
int n,q,k;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> q;
for(int i = 0;i < n;i ++ )cin >> a[i];
while(q -- )
{
int k;
cin >> k;
int l = 0,r = n - 1;
while(l < r)
{
int mid = l + r >> 1;
if(a[mid] >= k)r = mid;
else l = mid + 1;
}
if(a[l] != k)cout << -1 << ' ' << -1 << endl;
else
{
cout << l << ' ';
int l = 0,r = n - 1;
while(l < r)
{
int mid = l + r + 1 >> 1;
if(a[mid] <= k)l = mid;
else r = mid - 1;
}
cout << l << endl;
}
}
}
买铅笔
题目描述
输入
输出
样例输入
57
2 2
50 30
30 27
样例输出
54
源代码
简单模拟
#include <iostream>
using namespace std;
int n,ans = 1e9;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
for(int i = 1;i <= 3;i ++ )
{
int num,price;
cin >> num >> price;
int bags = n / num;
if(bags * num < n)bags ++ ;
int sum = bags * price;
ans = min(sum,ans);
}
cout << ans << endl;
return 0;
}