序言:
为期一周的欢乐的寒假集训终于结束了,很高兴能认识这么多的大佬和学长、学姐。很感谢ljw学长和陈宇老师为我们寒假培训所作出的贡献。
简单点评一下今天的考试试题,就在比赛前的中午,jlw学长说题目很水,很水,你们能信吗??反正我是信了,其实真的是很水(我太弱了),啊啊啊,还有一些题巨坑......话不多说,先放一下今天比赛的一些情况吧。
Information:
Sattus:
Rank List:
黑能,蒋世超布莱克,果光,谜题熊,老魏,孙芾(fu)岳真的好强呀!!
题目:
problem A:28的因子(NEFU 2101)
核心思路:暴力,先判断最多有几个7(位数越少他就会越小),然后一一枚举,看哪个条件符合,我太菜了,这是我最后AC的题,给想复杂了!
#include <bits/stdc++.h>
using namespace std;
int main()
{
//ios::sync_with_stdio(false);(玄学如果不注释会re)
int n;
while (~scanf("%d", &n))
{
int sum2 = 0;
int flag = 0, ans1, ans2; //4,7
sum2 = n / 7; //7的最大数量
for (int i = sum2; i >= 0; i--)
{
int tmp = n;
if ((tmp - i * 7) % 4 == 0)
{
flag = 1;
ans1 = (tmp - i * 7) / 4; //标记4的个数
ans2 = i; //标记7的个数
break;
}
}
if (!flag)
cout << "xinganheixiong" << endl;
else
{
for (int i = 1; i <= ans1; i++)
cout << "4";
for (int i = 1; i <= ans2; i++)
cout << "7";
cout << endl;
}
}
return 0;
}
problem B:陈老师发奖金(NEFU 2077)
核心思路:简单的结构体排序。
#include <bits/stdc++.h>
using namespace std;
const int M = 1e5 + 5;
struct student
{
int xh, cy, eng, math;
int sum;
int flag;
} a[M];
bool cmp(student a, student b)
{
if (a.sum != b.sum)
return a.sum > b.sum;
else
{
if (a.eng != b.eng)
return a.eng > b.eng;
else
{
return a.flag > b.flag;
}
}
}
int main()
{
ios::sync_with_stdio(false);
int n;
while (cin >> n)
{
memset(a, 0, sizeof(a));
for (int i = 1; i <= n; i++)
{
cin >> a[i].xh >> a[i].cy >> a[i].eng >> a[i].math;
a[i].flag = i;
a[i].sum += a[i].math + a[i].cy;
}
sort(a + 1, a + 1 + n, cmp);
int tmp;
if (n < 4)
tmp = n;
else
tmp = 4;
for (int i = 1; i <= tmp; i++)
cout << a[i].xh << " " << a[i].sum << endl;
}
return 0;
}
problem C:小明分蛋糕(NEFU 2096)
核心思路:本题类似于分整钱,简单题,要能看穿它正负情况是一样的话,就能很快做出来;
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
int a, b, x;
int ans;
cin >> t;
while (t--)
{
cin >> a >> b;
x = fabs(a - b);
ans = 0;
while (x >= 5)
{
ans += x / 5;
x -= x / 5 * 5;
}
while (x >= 2)
{
ans += x / 2;
x -= x / 2 * 2;
}
while (x >= 1)
{
ans += x / 1;
x -= x / 1;
}
cout << ans << endl;
}
return 0;
}
problem D:神奇的事情发生了(NEFU 2090)
核心思路:栈的运用,由于栈练习较少,我直接用字符串写的。
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
char a[105], b[105];
while (cin >> a)
{
int sum = 0, L;
L = strlen(a);
for (int i = 0; i < L; i++)
{
b[sum] = a[i];
if (b[sum] == 'o' && b[sum - 1] == 'o') //变化
{
b[sum - 1] = 'O'; //移位
sum--; //两个变成一个
}
if (b[sum] == 'O' && b[sum - 1] == 'O') //删除
sum -= 2; //一次是删除两个
sum++;//继续进行
}
for (int i = 0; i < sum; i++)
cout << b[i];
cout << endl;
}
return 0;
}
problem E:jwMM选酒店(NEFU 2083)
核心思路:不能暴力,会超时,核心思路,模拟,状态的转移;关注点在当前酒店是否能喝奶茶,如果能喝,就更新到这个位置的所以同色酒店的数量,ans+=当前同色酒店的数量(除本酒店以外);如果不能喝,就ans+=同色的酒店数量(此时的同色酒店数量是一定满足在当前酒店前能喝到奶茶)。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int M = 2e5 + 5;
LL ans = 0;
int color[M] = {0};
int num[55] = {0}; //同颜色酒店的数量
int main()
{
ios::sync_with_stdio(false);
int n, m, pp, pos = 0; //pos是标记能喝奶茶位置的最大值
cin >> n >> m >> pp; //酒店个数,颜色数目,最低消费
for (int i = 1; i <= n; i++) //暂时要住的
{
int col, ppi;
cin >> col >> ppi;
color[i] = col; //储存第i个位置是什么颜色
if (ppi <= pp) //i酒店能奶茶,加上之前的所以同色的酒店就ok
{
for (int j = pos + 1; j <= i; j++) //更新每种颜色酒店的数量
num[color[j]]++;
pos = i; //更新位置
ans += num[col] - 1;
}
else //i酒店不能喝奶茶,就加之前同色酒店数量就行
ans += num[col];
}
cout << ans << endl;
return 0;
}
problem F:jwMM的射箭游戏(NEFU 2078)
核心思路:gcd的运用(gcd就是代表的是公因子),坑点x-y可能有小于等于0的情况,要不是这一点,一血就是我的了QAQ~~坑。
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
int x1, y1, x2, y2;
while (cin >> x1 >> y1)
{
int num[500] = {0}, z = 0;
cin >> x2 >> y2;
int tmp1, tmp2;
tmp1 = __gcd(x1, y1);
tmp2 = x2 - y2;
if (tmp2 <= 0) //这个判断十分重要,题干说是正倍数
cout << "N" << endl;
else
{
if (__gcd(tmp1, tmp2) == 1) //如果是1的话他就没有除1以外的公因子
cout << "N" << endl;
else
cout << "Y" << endl;
}
}
return 0;
}
problem G:丹青玩游戏(NEFU 2082)
核心思路:二进制枚举,当时没有看出来,同时也要能清楚知道题干的叙述。
#include <bits/stdc++.h>
using namespace std;
struct lam
{
int kg[15];
} a[15];
int main()
{
ios::sync_with_stdio(false);
int n, m, tmp, tmp2;
while (cin >> n >> m) //n是开关数量,m是灯泡数量
{
long long ans = 0;
int pi[15] = {0};
memset(a, 0, sizeof(a));
for (int i = 1; i <= m; i++) //输入灯泡及其开关编号
{
cin >> tmp;
for (int j = 1; j <= tmp; j++)
{
cin >> tmp2;
a[i].kg[tmp2] = 1; //代表的是第ki编号的灯泡是否有相应的开关,即开关标记
}
}
for (int i = 1; i <= m; i++) //输入灯泡亮的程度;
cin >> pi[i];
for (int i = 0; i < (1 << n); i++) //枚举n(开关数量)
{
int dp[15] = {0};
for (int j = 0; j < n; j++)
{
if (i & (1 << j)) //枚举开关开闭的状态
dp[j + 1] = 1;
else
dp[j + 1] = 0;
}
int z, judge = 0;
for (int k = 1; k <= m; k++) //判断每一个是否成立
{
int sum = 0;
for (z = 1; z <= n; z++)
if (a[k].kg[z] && dp[z]) //ki编号的灯是否有相应的开关
sum++;
if (sum % 2 != pi[k]) //亮度的判断
{
judge = 1;
break;
}
}
if (!judge)
ans++;
}
cout << ans << endl;
}
return 0;
}
problem H:分糖果(NEFU 2100)
核心思想:二分查找。你的ans一定会小于m值,目的是找到两个数的取余后的加和最大。
- 利用取余的性质(a+b)%m=(a%m+b%m)%m,对输入进行处理。
- 从i=1,一直查到i=n,最理想中的返回值是m-1,所以对其当作切入点,利用lower_bound()查找大于等于m-a【i】的坐标。
- 关键:细节处理,设查找的数是tmp,lower_bound()的防越界处理,当a【i】中的所有数都小于tmp的时候,他的返回值是1+n,是会越界的,要进行后越界处理;当a【i】中的所有数都小于tmp的时候,他的返回值是1,但是你要找的是小于最近一个tmp,要是减去1也是会出界,要做前出界处理。
- 最后一步,如果没有取到x为m-a[i]-1的话就不一定是最优解 所以和最后一个数相加判断。
#include <bits/stdc++.h>
using namespace std;
const int M = 1e5 + 5;
int a[M], m;
int main()
{
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--)
{
int n;
memset(a, 0, sizeof(a));
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
a[i] %= m;
}
sort(a + 1, a + 1 + n);
int tmp1, tmp2, ans = 0;
for (int i = 1; i <= n; i++)
{
tmp1 = m - a[i];
tmp2 = lower_bound(a + 1, a + 1 + n, tmp1) - a;
if (tmp2 - 1 > 0 && tmp2 != 1 + n) //双倍防越界
{
if (tmp2 - 1 != i)
ans = max(ans, a[tmp2 - 1] + a[i]);
else if (tmp2 - 2 > 0) //如果他俩是同一个位置,就要向前移一位,不能加本身的
ans = max(ans, a[tmp2 - 2] + a[i]);
}
if (i != n) //防止加不到最大值的时候
ans = max((a[i] + a[n]) % m, ans);
}
cout << ans << endl;
}
return 0;
}
problem I:抹发胶(NEFU 2088)
核心思路:暴力。
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
int t;
while (cin >> t)
{
int n, a[105];
while (t--)
{
int minn[105] = {0};
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
for (int j = 1; j < i; j++) //在输入的同时判断前一名是否小于后一名
{
if (a[i] > a[j])
minn[i]++;
}
}
for (int i = 1; i <= n; i++)
{
cout << minn[i];
if (i == n)
cout << endl;
else
{
cout << " ";
}
}
}
}
return 0;
}
problem J:天哥的难题(NEFU 2085)
核心思路:数学证明题,后续证明。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod = 1e9 + 7;
LL fastpow(LL a, LL b)
{
int res = 1;
while (b)
{
if (b & 1)
res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
int main()
{
ios::sync_with_stdio(false);
int m;
while (cin >> m)
{
cout << fastpow(3, m) << endl;
}
return 0;
}
problem K:煊哥的数字游戏(NEFU 2084)
核心思路:防AK的题,巨无敌难的数学推导。异或是不进位的加法。
- sum=a1+a2+...+am,num=a1⊕a2⊕...⊕am。这样就是解sum+b=num⊕2*b。
- 若两边相等,则它的二进制每一位都要相等,模拟等式左边+b,等式右边⊕2*b的过程,从第一位逐个比较,直到sum=num。
- 当sum=num的时候,等式左边=sum+b=sum',要解b,只需要sum'-sum即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int a[100005];
int main()
{
ios::sync_with_stdio(false);
int m;
LL sum = 0, num = 0, tmp, i = 0;
cin >> m;
for (int i = 1; i <= m; i++)
{
cin >> a[i];
sum += a[i];
num ^= a[i];
}
LL ans = sum; //记录原来的sum
num *= 2;
while (sum != num)
{
i++;
tmp = (LL)1 << i; //比较每一位是否相同
if (sum % tmp != num % tmp)
{
sum += tmp >> 1;
num ^= tmp;
}
}
cout << sum - ans << endl;
return 0;
}
problem L:吃辣条
核心思路:快排+暴力。
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
int n;
while (cin >> n)
{
int a[105];
for (int i = 1; i <= n; i++)
cin >> a[i];
sort(a + 1, a + 1 + n);
cout << a[n - 1] << " " << a[2] << endl;
}
return 0;
}