文章目录
总结
5、7题没AC。
前4题简单,10min内搞定。第五题卡了25min没AC。6题11min较简单,不熟悉顺序表的插入删除操作。8题12min,简单板子题。7题7min到时间了,10min过的样例。5题卡了25min,差1分。
#大勾股定理
7-5 大勾股定理
25min 14/15
题意
给定数字n,总能找到一个等式形式如下:
s
2
+
.
.
.
+
(
s
+
n
)
2
=
(
s
+
n
+
1
)
2
+
.
.
.
+
(
s
+
2
∗
n
)
2
s^2 +...+ (s+n)^2 = (s+n+1)^2+...+(s+2*n)^2
s2+...+(s+n)2=(s+n+1)2+...+(s+2∗n)2
要求找到并输出。
思路
正确思路:
- 根据给定公式进行数学简化,找到s与n的关系。
- 直接输出即可。
错误思路: - 相当于有数列
A
s
=
[
(
s
2
+
.
.
.
+
(
s
+
n
)
2
)
]
−
[
(
s
+
n
+
1
)
2
+
.
.
.
+
(
s
+
2
∗
n
)
2
]
A_s = [(s^2 +...+ (s+n)^2)] - [(s+n+1)^2+...+(s+2*n)^2]
As=[(s2+...+(s+n)2)]−[(s+n+1)2+...+(s+2∗n)2]
- 求 A s = 0 A_s = 0 As=0
- 而 A s + 1 = A s − s 2 + 2 ∗ ( s + n + 1 ) 2 − ( s + 2 ∗ n + 1 ) 2 A_{s+1} = A_s - s^2 + 2*(s+n+1)^2 - (s+2*n+1)^2 As+1=As−s2+2∗(s+n+1)2−(s+2∗n+1)2
-
A
s
+
1
−
A
s
=
4
s
(
n
+
1
)
+
2
(
n
+
1
)
2
−
2
(
s
(
2
n
+
1
)
)
−
(
2
n
+
1
)
2
A_{s+1} - A_s= 4s(n+1)+2(n+1)^2 - 2(s(2n+1))-(2n+1)^2
As+1−As=4s(n+1)+2(n+1)2−2(s(2n+1))−(2n+1)2
= 4sn + 4s + 2n2 + 4n + 2 -4sn - 2s - 4n2 - 4n - 1
= 2s + 1 - 2n^2 - A_1 = 1+…+n^2
- 遍历找满足条件As即可.
小结
- 能用数学方法简化的一定要先考虑用数学方法简化。
- 开始被卡时间,想到滑动窗口,就每次s++时 − s 2 + 2 ∗ ( s + n + 1 ) 2 − ( s + 2 ∗ n + 1 ) 2 - s^2 + 2*(s+n+1)^2 - (s+2*n+1)^2 −s2+2∗(s+n+1)2−(s+2∗n+1)2 。但是仍然TLE。思考可能pow用多了,于是先用f数组存所有下标对应平方,但是MLE了。
- 这时候想折个中,一半f数组,一半pow函数。这种思想是不对的,只是可以骗分,也没过14分。
- 交卷后考虑到可以二分,算了一下时间应该会短些。
解法1 - 数学 - 待检验
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main(){
int n, i, j; cin>>n;
for(i = n * (2 * n + 1), j = 1; j <= n + 1; i ++, j ++){
printf("%lld^2", i);
if(j != n + 1) printf(" + ");
}
printf(" =\n");
for(int j = 1; j <= n; i++, j ++){
printf("%lld^2", i);
if(j != n) printf(" + ");
}
return 0;
}
解法2 - 二分 - 待检验
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n, s, f[5000000], l, r;
int cmp(int s){
int l = 0, r = 0;
for(int i = s; i <= s + n; i ++)
l += pow(i, 2);
for(int i = s + n + 1; i <= s + 2 * n; i ++)
r += pow(i, 2);
if(l < r) return 1;
else if(l > r) return 3;
else return 2;
}
signed main(){
cin>>n;
int l = 1, r = 10000000000;
while(l <= r){
int m = l + r >> 1;
int ptr = cmp(m);
if(ptr == 1) l = m + 1;
else if(ptr == 3) r = m - 1;
else{
s = m;
break;
}
}
for(int i = 0; i <= n; i ++){
if(i) printf(" + ");
printf("%d^2", i + s);
}
cout<<" =\n";
for(int i = n + 1; i <= 2 * n; i ++){
if(i != n + 1) printf(" + ");
printf("%d^2", i + s);
}
return 0;
}
题目
大勾股定理是勾股定理的推广:对任何正整数 n 存在 2n+1 个连续正整数,满足前 n+1 个数的平方和等于后 n 个数的平方和。例如对于 n=1 有 3 2 + 4 2 = 5 2 3^2+4^2=5^2 32+42=52;n=2 有 1 0 2 + 1 1 2 + 1 2 2 = 1 3 2 + 1 4 2 10^2+11^2+12^2=13^2+14^2 102+112+122=132+142 等。给定 n,本题就请你找出对应的解。
输入格式:
输入在一行中给出正整数 n(≤ 1 0 4 10^4 104)。
输出格式:
分两行输出满足大勾股定理的解,格式如下:
a[0]^2 + a[1]^2 + ... + a[n]^2 =
a[n+1]^2 + ... + a[2n]^2
其中解的数列 a[0] ... a[2n]
按递增序输出。注意行首尾不得有多余空格。
输入样例:
3
输出样例:
21^2 + 22^2 + 23^2 + 24^2 =
25^2 + 26^2 + 27^2
7-7 约会大作战
7min 1/20, 10min过样例
题意
给定两组人的人员数量n、m,和询问数q。
然后给出矩阵a[n][m]
和 b[m][n]
表示两组对对方好感度分别为多少。
最后给出q组询问对,问哪几对能匹配成功。
思路
- 记录n、m、q。矩阵存在a、b中。
- 然后循环q次:
- 首先判断两个人是否有人出去了,出去则匹配失败,continue
- 记录成员前两次约会次数在
cnt1[101], cnt2[101]
以及对这两次进行最大值更新mp1[101], mp2[101]
- 匹配成功则两个人出去,
out1[101], out2[101]
中记录。
题解 - 待检验
#include<bits/stdc++.h>
using namespace std;
int n, m, q,x, y, a[101][101], b[101][101], cnt1[101], cnt2[101], num, mp1[101], mp2[101], out1[101], out2[101];
int main(){
cin>>n>>m>>q;
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= m; j ++)
cin>>a[i][j];
for(int i = 1; i <= m; i ++)
for(int j = 1; j <= n; j ++)
cin>>b[i][j];
for(int i = 0; i < q; i ++){
cin>>x>>y;
if(out1[x] || out2[y]) continue;
bool f = true;
if(cnt1[x] < 2){
f = false;
cnt1[x]++;
mp1[x] = max(mp1[x], a[x][y]);
}
if(cnt2[y] < 2){
f = false;
cnt2[y]++;
mp2[y] = max(mp2[y], b[y][x]);
}
if(f == true){
num ++;
cout<<x<<' '<<y<<endl;
out1[x] = true;
out2[y] = true;
}
}
if(num == 0) puts("PTA is my only love");
return 0;
}
7-6 矩阵列平移
11min
思路
- 数组存入
int f[N][N]
。int ptr
记录偏移量。 - 将每列看做一个顺序表,遍历偶数个列,计算偏移量,向下偏移,然后对前偏移量个元素赋值为x。
- 计算偏移量:从1-k循环。
- 然后循环每行、每列,计算每行元素和。
解法1 - AC
#include<bits/stdc++.h>
using namespace std;
int n, k, x, f[101][101], ans[101];
int main(){
cin>>n>>k>>x;
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= n; j ++)
cin>>f[i][j];
int ptr = 0;
for(int i = 2; i <= n; i += 2){
ptr = ptr % k + 1;
for(int j = n; j >= ptr; j --)
f[j][i] = f[j - ptr][i];
for(int j = 0; j <= ptr; j ++)
f[j][i] = x;
}
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= n; j ++){
cout<<f[i][j]<<' ';
ans[i] += f[i][j];
}
cout<<endl;
}
for(int i = 1; i <= n; i ++){
if(i - 1)cout<<' ';
cout<<ans[i];
}
return 0;
}
7-8 浪漫侧影
12min
思路
- 常规造树,额外记录树高。
- 层序遍历。两个指针分别记录上一个弹出元素pre,和当前队列头部元素ptr。每次访问到下一层,将pre记入ansr数组对应高度的位置,将ptr记入ansl数组对应高度的位置。
- 按序输出ansl和ansr数组即可。
题解
#include<bits/stdc++.h>
using namespace std;
int n, in[40], post[40], mh;
int ansl[40], ansr[40];
struct node{
int k, h;
struct node*l, *r;
};
node* mt(int il, int ir, int pl, int pr, int h){
mh = max(mh, h);
if(il > ir) return NULL;
node * t = (node*)malloc(sizeof(node));
t->k = post[pr];
t->h = h;
int i = il;
while(in[i] != post[pr])i++;
t->l = mt(il, i - 1, pl, pl + i - 1 - il, h + 1);
t->r = mt(i + 1, ir, pl + i - il, pr - 1, h + 1);
return t;
}
int main(){
cin>>n;
for(int i = 0; i < n; i ++) cin>>in[i];
for(int i = 0; i < n; i ++) cin>>post[i];
node * t = mt(0, n - 1, 0, n - 1, 0);
queue<node*> que; que.push(t);
ansl[0] = ansr[0] = t->k;
int th = 0;
node * tn = t;
while(que.size()){
auto tar = que.front();
if(tar->h > th){
ansr[th] = tn->k;
th = tar->h;
ansl[th] = tar->k;
}
tn = tar;
que.pop();
if(tar->l) que.push(tar->l);
if(tar->r) que.push(tar->r);
}
ansr[th] = tn->k;
cout<<"R:";
for(int i = 0; i < mh; i ++)
printf(" %d", ansr[i]);
puts("");
cout<<"L:";
for(int i = 0; i < mh; i ++)
printf(" %d", ansl[i]);
return 0;
}
7-1 自动编程
1min
#include<bits/stdc++.h>
using namespace std;
int n;
int main(){
cin>>n;
printf("print(%d)", n);
return 0;
}
7-2 加油冲鸭
3min
#include<bits/stdc++.h>
using namespace std;
int n, m, s, sum;
int main(){
cin>>n>>m>>s;
sum = n - m * s;
if(sum <= n / 2) printf("hai sheng %d mi! chong ya!", sum);
else printf("hai sheng %d mi! jia you ya!", sum);
return 0;
}
7-3 520的表白
2min
#include<bits/stdc++.h>
using namespace std;
int main(){
string r; cin>>r;
for(int i = 0; i < 520; i ++)
puts(r.c_str());
return 0;
}
7-4 奇葩楼层
2min
#include<bits/stdc++.h>
using namespace std;
int main(){
int n, d; cin>>n>>d;
int cnt = n;
for(int i = 1; i <= n; i ++){
string s = to_string(i);
if(s.find('0' + d) != -1) cnt--;
}
cout<<cnt;
return 0;
}