蓝桥杯选拔赛总结+补题
1.签到啦
题解:签到题,比较容易,但是本菜鸡一上来还用循环搞,判定质数什么的,真是无语。。后来灵光一闪,n>=1,<=5的时候,没有答案,n>=5的时候,分奇偶,偶数时,定下一个质数因子为2,那么n-2也是偶数,是合数,奇数时,定下一个质数因子为3,n-3为偶数,因为奇数加偶数是奇数,大于2的偶数是合数。
用了一些奇偶的性质和质数,合数的性质,做题的时候差点没反应过来。。
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int main() {
int t, n;
cin >> t;
while (t--) {
cin >> n;
if (n >= 1 && n <= 5)
printf("-1\n");
else {
if (n % 2 == 0) { //n是偶数,取一个质数因子为2,n-2必是偶数,则一定是个合数
printf("2 ");
printf("%d\n", n - 2);
}
if (n % 2 == 1) { //n是奇数,取一个质数因子为3,n-3必是偶数,则一定是个合数(奇+偶=奇)
printf("3 ");
printf("%d\n", n - 3);
}
}
}
}
2.房子塌了
题解:这个题就是已知面积求最小周长,一下子就想到了长等于宽的时候取最值,高中的均值不等式,个人觉得题目应该再强调一下矩形边长为整数,这个题里不是所有的都能长等于宽,但是我们可以让长和宽更加接近,这时候的周长最小。
这个题的关键在于if判断的那句能不能想到
AC代码:
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
int s;
while(cin>>s)
{
int a,b;
for(a=s;a>=1;a--)//长递减,宽递增
{
b=s/a;
if(a*b==s&&b>=a)//此处需特判,因为不是整数的时候,会自动取整,a*b就不等于s了
break;
}
printf("%d\n",2*(a+b));
}
}
3.你好!李焕英
这个题当时做的时候没想出来,后来补题的时候也错了挺多次,真的是整了半天,原因是数组开小了
题解:其实这道题思路很简单,因为n<=1000,所以直接暴力枚举就好
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int a[100000 + 10];
int b[200000 + 10];//b数组至少开到200000,如 5
int main() { //100000 100000 100000 100000 100000
int n;
while(cin >> n){
memset(b,0,sizeof(b));
for (int i = 0; i < n; i++)
cin >> a[i];
int ans=0;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {//直接枚举
b[a[i] + a[j]]++;//类似于桶
ans=max(ans,b[a[i]+a[j]]);//直接边循环边比
}
}
printf("%d\n",ans);
}}
4.ICPC
这道题要求数量最多,所以我一开始想的是贪心,循环,先把啥都不会的菜鸡学生简称C都组完,因为如果有C在的话,A和B只要各选一人就好,这样每次选完剩下的人肯定是最多的情况,人多的话组队情况就可能会相应变多,C选完之后,剩下来的学生A B数量都大于0的话, 人多的-2,人少的-1,因为团队数量最大的话,肯定每次拿出一部分人之后,剩下的人较多才好,有一个等于0直接break输出即可,结果在Test 3的时候TLE了,一看题目1e4和1e8 ,如果数据小的话,说不定这个方法就能过了,所以也记录一下
正确思路:把所有人平均分成3堆,每堆人数为D,分别表示会代码的人数,会数学的人数和菜鸡的人数,再将A,B与D比较,如果A,B都比D大,那么一共就有D个完美团队,因为我们可以从这三堆里各取出一人组队,若有如9 9 1此类情况,就可以把多出来的会代码的人,会数学的人移到菜鸡里,当成菜鸡,再从每堆各取一人,如果A,B中有比D小的,如A<B<D,那么就只能组成A个完美团队,如 239,则只能组成2个完美团队,否则会代码的人数不够
#include<stdio.h>
int main()
{
int q;
scanf("%d",&q);
while(q--)
{
int c,m,x,t1,t2,k;
scanf("%d%d%d",&c,&m,&x);
if(c<=m)
k=c;
else
k=m;
t1=(c+m+x)/3;
if(t1<=k) printf("%d\n",t1);
else printf("%d\n",k);
}
return 0;
}
5.唐人街探案3
题解:根据题意模拟即可
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int a[100000+10];
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++)
cin >> a[i];
int sum1 = 0, sum2 = 0;
int i, j;
for (i = 0, j = n - 1; i <= j;) {
if (sum1 <= sum2) {
sum1 += a[i];
i++;
} else {
sum2+= a[j];
j--;
}
}
printf("%d %d", i, n - i);
}
6.云顶之弈
题解:若是1*1的棋盘,小明必败,棋盘中每一个位置只有两种状态,必胜态或者必败态,只要是能将棋子移到必败点的点一定是必胜点,由此推演
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{ int n,m;
while(cin>>n>>m&&n&&m)
{
if(n%2==1&&m%2==1)
printf("What a pity!\n");
else
printf("Wonderful!\n");
}
}
7.小王蹬三轮
题解:差分即可
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int a[100000 + 10];
int main() {
int n, x, y;
while (cin >> n && n) {
memset(a, 0, sizeof(a));
for (int i = 1; i <= n; i++) {
cin >> x >> y;
a[x] ++;
a[y + 1]--;
}//差分
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += a[i];
if (i == 1)
printf("%d", sum);
else
printf(" %d", sum);//处理行末的空格
}
printf("\n");
}
}
还有的题争取抽时间继续补吧hhh,开学辽!