- bs来送签到啦
简单思考下就知道无论选择何种路线从左上角到右下角,通过平移后就等价于先向下走到底再向右走到底,所以只要两个循环累加下两条边的的价值就能得到答案(注意循环左右边界),当然也可以直接使用求和公式输出答案。
代码:
#include <stdio.h>
int main() {
int n, m, tt;
scanf ("%d", &tt);
while (tt -- ){
int n, m, ans = 0;
scanf("%d %d", &n, &m);
for (int i = 2; i <= n; i ++ ) ans += i;
for (int i = 2; i <= m; i ++ ) ans += i;
printf ("%d\n", ans);
}
return 0;
}
1002.大名鼎鼎的Forblue王国
本题直接暴力求出所有点的坐标之差(x,y),然后对于每个坐标(x,y)同时除以gcd(x,y),把所有处理结果存起来,去重即可。
代码:(此代码为C++代码,C语言可以用结构体写)
#include <bits/stdc++.h>
using namespace std;
int n;
vector<pair<int,int>>p,q;
int main()
{
scanf("%d",&n);
for(int i = 1; i <= n; i ++ )
{
int x, y;
scanf("%d %d",&x,&y);
p.push_back({x,y});
}
for(int i = 0; i < n; i ++ )
{
for(int j = 0; j < n; j ++ )
{
if(i != j)
q.push_back({p[i].first - p[j].first,p[i].second - p[j].second});
}
}
for(int i = 0; i < q.size(); i ++)
{
if(q[i].first == 0){
if(q[i].second > 0) q[i].second = 1;
else q[i].second = -1;
}
else if(q[i].second == 0){
if(q[i].first > 0) q[i].first = 1;
else q[i].first = -1;
}else{
int x = abs(__gcd(q[i].first, q[i].second));
q[i].first /= x, q[i].second /= x;
}
}
sort(q.begin(),q.end());
q.erase(unique(q.begin(), q.end()),q.end());
printf("%d\n",q.size());
return 0;
}
1003.QQ飞车的大比试
题目都是一大半都是废话,输出2x - 1就行
#include <stdio.h>
int main()
{
int t;
scanf("%d",&t);
while(t -- )
{
long long x;
scanf("%lld",&x);
printf("%lld\n", 2 * x -1);
}
return 0;
}
- 简单的数组问题
只要讨论下下出现最多的那个数的数量maxn和n的奇偶就行。
当n为奇数,maxn小于n / 2 + 1, 答案就是1,maxn大于
n / 2 + 1的话答案就是maxn - (maxn - n)。
当n为偶数,maxn小于n / 2,答案就是0,maxn大于n / 2,答案就是maxn - (maxn - n)。
代码:
#include <stdio.h>
int max(int a, int b)
{
if(a >= b) return a;
else return b;
}
int main()
{
int a[100000], b[100000];
int t;
scanf("%d",&t);
while(t -- )
{
int n;
scanf("%d",&n);
for(int i = 1; i <= 100000; i ++ ) b[i] = 0;
int maxn = -1;
for(int i = 1; i <= n; i ++ )
{
scanf("%d",&a[i]);
b[a[i]] ++;
maxn = max(maxn, b[a[i]]);
}
if(n % 2 == 0){
if(maxn <= n / 2){
printf("0\n");
}else{
printf("%d\n", maxn - (n - maxn));
}
}else{
if(maxn <= n / 2 + 1){
printf("1\n");
}else{
printf("%d\n", maxn - (n - maxn));
}
}
}
return 0;
}
- bs的QQ飞车
如果所有人在同一组里,由于每个人都可能会禁掉不同的地图,因此我们应该有n + 1张地图;
如果每个人单独一组,则需要2张图;
其余情况下,只需要3张地图即可满足题意。
#include <stdio.h>
int main()
{
int t;
scanf("%d",&t);
while(t -- )
{
int n, m;
scanf("%d %d",&n, &m);
if(m == 1) printf("%d\n", n + 1);
else if(n == m) printf("2\n");
else printf("3\n");
}
return 0;
}
1006.bs努力不做舔狗
这道题的答案很明显,就是输出所给数中最大的那一位数字,但是注意输入的数据范围是十万位的数,用任何整数类型都存不下这样的范围,所以本题需要我们读入一个字符串来表示输入,遍历字符串中每一位得到最大值即可,注意字符型变量要在比较时转化成整型变量,另外当最大值是0时的答案是1,特判下即可。
代码:
#include <stdio.h>
#include <string.h>
int max (int a, int b) {
if(a >= b) return a;
else return b;
}
int main() {
int tt;
scanf ("%d", &tt);
while (tt -- ) {
int ans = -1;
char s[100010];
scanf ("%s", s);
for (int i = 0; i <= strlen(s); i ++ ) ans = max (ans, s[i] - '0');
if (ans != 0) printf ("%d\n", ans);
else puts("1");
}
return 0;
}
- bs的数组匹配
n是2000,本题可以先预处理出1- n中所有数的二进制,再暴力匹配,统计重合数等于k的个数就行。
#include <bits/stdc++.h>
using namespace std;
int n, k;
string a[2010];
vector<int> binary(int n)
{
vector<int>q;
while(n)
{
q.push_back(n % 2);
n /= 2;
}
reverse(q.begin(),q.end());
return q;
}
bool check(int x, int y)
{
for(int i = 0; i + k <= a[x].length(); i ++ )
for(int j = 0; j + k <= a[y].length(); j ++ )
if(a[x].substr(i, k) == a[y].substr(j, k)) return true;
return false;
}
int main()
{
scanf("%d %d",&n, &k);
for(int i = 1; i <= n; i ++ )
{
vector<int>q = binary(i);
for(int j = 0; j < q.size(); j ++ ) a[i] += (q[j] + '0');
}
int ans = 0;
for(int i = 1; i <= n; i ++ )
for(int j = i + 1; j <= n; j ++ )
if(check(i, j)) ans ++;
cout << ans << endl;
return 0;
}
1008.wzgg的天赋
寻找最长回文子串,可以从一个回文子串中间开始往两头找,
利用循环遍历字符串数组,并以这一点为中点往两头找
#include <stdio.h>
#include <string.h>//求字符串数组长度需要strlen()函数的头文件
int expandAround(char str[], int left, int right)
{
while(str[left] == str[right] && left >= 0 && right < strlen(str))
{
left--;
right++;
}
int s = right - left - 1;
return s;
}
int max(int a, int b)//定义的函数,返回两数中的较大值
{
if(a > b)//如果a>b,则返回a
return a;
return b;//同理返回b。注意,当a=b时,返回两者中任意一个都可,这里定义为返回b
}
int main()
{
char str[1000],c;
int j,i,n,x;
scanf("%d",&n);
c = getchar();//定义的char类型的c,用来消去输入字符串前面的回车
for(j=0;j<n;j++)
{
gets(str);
int m = 0;
x = strlen(str);
for(i = 0; i <x; i++)
{
int len1 = expandAround(str, i, i);//长度是奇数的回文字串
int len2 = expandAround(str, i, i + 1);//长度是偶数的回文字串
int len = max(len1, len2);
m = max(m, len);
}
printf("%d\n", m);
}
return 0;
}
1009.不难的题目
寻找最小魔王数组的大小。魔王数组的要求是对于任何一位数组的元素,他的a-1和a-2至少有一个在数组中,所以可以从1开始往上累加2,当一个数加上后总和大于等于n,将其除2即为所求。
#include <stdio.h>
int main(){
int n,x,i,s=1,t;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&x);
s=0;
t=1;
while(s<x){
s=s+t;
t=t+2;
}
printf("%d\n",t/2);
}
return 0;
}
1010.喵喵喵?
这道题注意理解题意,并没有要求两个相等的值中间所有的值都要小于这两个值,只要保证之间的最小值小于端点值就符合条件。
令此时的n=19,当我们没有限制其他条件时,为了保证每一位的值尽可能的大,我们可以将每一位的值设为20,此时的序列为:
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
但由于相邻的值不能相等,所以为了满足这层条件,我们应将每两个20之间间位置先空出,此时的序列为:
20 _ 20 _ 20 _ 20 _ 20 _ 20 _ 20 _ 20 _ 20 _ 20
现在再考虑向序列中加入19,如果将剩余的每个空位都放入19的话,两个相邻的19之间的最小值会变成20,此时的序列为:
20 19 20 19 20 19 20 19 20 19 20 19 20 19 20 19 20 19 20
这样显然是不行的,所以我们需要将每两个相邻的19之间的空位放置更小的数,腾出空位后的序列:
20 19 20 _ 20 19 20 _ 20 19 20 _ 20 19 20 _ 20 19 20
现在考虑18,同19一样,两个相邻的18之间要预留一个空位:
20 19 20 18 20 19 20 _ 20 19 20 18 20 19 20 _ 20 19 20
之后17:
20 19 20 18 20 19 20 17 20 19 20 18 20 19 20 _ 20 19 20
16:
20 19 20 18 20 19 20 17 20 19 20 18 20 19 20 16 20 19 20
现在我们可以发现:
20在序列中第一次出现在20的位置上,之后每增加21的位置也是20。
19出现在21,之后每次增加22
18出现在22,之后每次增加23
17出现在23,之后每次增加24
16. .....
x 出现在2^(20 - x),之后每次增加2^(20-x+1)
于是这道题的答案已经明朗了,我们可以通过两层循环先预处理出最长的序列,之后输出长度为n的子序列即可。
代码:
#include <stdio.h>
#include <math.h>
int main() {
const int N = 10005;
int q[N];
for (int i = 1; i <= 20; i ++ )
for (int j = pow (2, i - 1); j <= N; j += pow (2, i) )
q[j] = 20 - i + 1;
int n;
scanf ("%d", &n);
for (int i = 1; i <= n; i ++ ) printf ("%d ", q[i]);
printf ("\n");
return 0;
}
标签:练习题,20,第三次,int,scanf,新生,19,return,include
From: https://www.cnblogs.com/Chesedss/p/16945130.html