最后一届蓝桥杯了tot
第一题握手问题,直接算出来了,0代码
握手问题
第二题小球反弹,虽然思路大体对了,但是只考虑了去没考虑回来(没*2)
小球反弹
#include <bits/stdc++.h>
using namespace std;
int main(){
long long t=1,x=343720,y=233333;
while(1){
if((15*t)%x==0&&(17*t)%y==0) break;
t++;
}//往右延长同样的长方形 当走到第t个长方形的左上角 就算是回到了左上角了
printf("%.2f",2*sqrt(15*15*t*t+17*17*t*t));//如果小球刚好射向角落,则按入射方向原路返回因此*2
return 0;
}
第三题好数,直接暴力枚举就行
好数
第四题R格式,高精度板子题,要注意小数点的处理
也可以开double骗30%的分。
高精度要注意读入和输出的顺序!!!!!
R格式
#include <bits/stdc++.h>
using namespace std;
void mul(vector<int> &A,int b){
int t = 0;
for(int i = 0;i < A.size();i++){
t += A[i] * 2;
A[i] = t % 10;
t /= 10;
}
if(t) A.push_back(t);
}
void add(vector<int> &A,int k,int l){
int t = l;
for(int i = k;i < A.size();i++){
t += A[i];
A[i] = t % 10;
t /= 10;
}
if(t) A.push_back(t);
}
int main(){
int n;
string d;
vector<int> A;
cin >> n >> d;
reverse(d.begin(),d.end());
int dot = d.find('.');
for(auto c : d){
if(c!='.'){
A.push_back(c - '0');
}
}
while(n--){
mul(A,2);
}
if(A[dot - 1] >= 5){
add(A,dot,1);
}
for(int i = A.size() - 1 ;i >= dot;i--){
cout << A[i];
}
}
第五题宝石组合,正解是化简公式,可惜我数学不好,直接暴力做的,暴力的30%没拿到,这题不看了,跳了!!!
宝石组合
第六题数字接龙,经典dfs题,但是要考虑交叉情况,一开始交的时候没考虑交叉,能拿75%,这告诉我们在考场就算不能完美做出来,至少先交上,没准就混上分了~
考虑交叉的话开一个四维数组,存储走过的斜线的起点和终点,在下次走斜线的时候判断
数字接龙
我自己写的是用一个ans存,但是后来改成了set,最后又调整了一下dfs的做法,改成bool,然后用string存答案,我觉得也是个不错的思路
#include <bits/stdc++.h>
using namespace std;
const int N = 11;
bool st[N][N];
bool edge[N][N][N][N];
int mp[N][N];
string path;
int n,k;
int dx[] = {-1,-1,0,1,1,1,0,-1};
int dy[] = {0,1,1,1,0,-1,-1,-1};
bool check(int x,int y){
return (x>=0&&x<n&&y>=0&&y<n);
}
bool dfs(int x,int y){
if(x == n - 1 && y == n - 1){
return path.size() == n * n - 1;
}
st[x][y] = true;
for(int i = 0;i < 8;i++){
int nex = x + dx[i],ney = y + dy[i];
if(!check(nex,ney)) continue;
if(st[nex][ney]) continue;
if(mp[nex][ney] != (mp[x][y] + 1) % k) continue;
if(i % 2 && (edge[x][ney][nex][y] || edge[nex][y][x][ney])) continue;
edge[x][y][nex][ney] = true;
path += i + '0';
if(dfs(nex,ney)) return true;
path.pop_back();
edge[x][y][nex][ney] = false;
}
st[x][y] = false;
return false;
}
int main(){
cin >> n >> k;
for(int i = 0;i < n;i++){
for(int j = 0;j < n;j++){
cin >> mp[i][j];
}
}
if(!dfs(0,0)) cout << -1 << endl;
else cout << path << endl;
return 0;
}
//#include <bits/stdc++.h>
//using namespace std;
//const int N = 11;
//bool st[N][N];
//int mp[N][N];
//int n,k;
//int dx[] = {-1,-1,0,1,1,1,0,-1};
//int dy[] = {0,1,1,1,0,-1,-1,-1};
//set<vector<int>> ans;
//
//bool cmp(vector<int> a,vector<int> b){
// for(int i = 0;i < a.size();i++){
// if(a[i] != b[i]) return a[i] > b[i];
// }
// return true;
//}
//
//bool check(int x,int y){
// return (x>=0&&x<n&&y>=0&&y<n);
//}
//
//void dfs(int x,int y,int e,vector<int> a){
// int t;
// if(a.size() == n * n - 1 && x == n-1 && y == n-1){
// ans.insert(a);
// return;
// }
//
// if(e == k - 1){
// t = 0;
// }else{
// t = e + 1;
// }
// for(int i = 0;i < 8;i++){
// int nex = x + dx[i],ney = y + dy[i];
// if(check(nex,ney) && !st[nex][ney] && mp[nex][ney] == t){
// st[nex][ney] = true;
// a.push_back(i);
// dfs(nex,ney,t,a);
// a.pop_back();
// st[nex][ney] = false;
// }
// }
//}
//
//int main(){
// cin >> n >> k;
// for(int i = 0;i < n;i++){
// for(int j = 0;j < n;j++){
// cin >> mp[i][j];
// }
// }
//
// st[0][0] = true;
// vector<int> a;
// dfs(0,0,mp[0][0],a);
//
// if(ans.empty()){
// cout << -1 << endl;
// }else{
// auto v = *ans.begin();
// for(auto i : v){
// cout << i;
// }
// }
//// for(int i = 0;i < a.size();i++){
//// cout << ans[i];
//// }
//}
最后一题拔河,同样是暴力没做出来,可能是没考虑不选某个人情况,我这里考虑的是全部选上了
看了眼题解,有个暴力能做出来的,就po这个了,还有前缀和的(我自己做的也是前缀和)看着比暴力麻烦很多
拔河
#include <bits/stdc++.h>
using namespace std;
long long a[1000];
vector<long long> s;
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
// 枚举i,j区间的力量和
for (int i = 0; i < n; i++)
{
long long t = 0;
for (int j = i; j < n; j++)
{
t += a[j];
s.push_back(t);
}
}
//若两数的差最小,其排序后一定相邻
sort(s.begin(), s.end());
long long ans = 1e9;
//找到最小的力量差
for (int i = 1; i < s.size(); i++)
{
ans = min(ans, s[i] - s[i - 1]);
}
cout << ans;
return 0;
}
//前缀和枚举+二分
// #include<bits/stdc++.h>
// using namespace std;
// const int N = 1e3+10;
// long long a[N];
// int n;
// multiset<long long>s;
// long long minn(long long a,long long b){
// if(a<b) return a;
// else return b;
// }
// int main(){
// ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);//取消同步流
// cin>>n;
// for(int i = 1;i<=n;i++) {
// cin>>a[i];
// a[i]+=a[i-1];//构造前缀和
// }
// for(int i = 1;i<=n;i++){
// for(int j = i;j<=n;j++){
// s.insert(a[j]-a[i-1]);//枚举右区间所有情况先加入set中
// }
// }
// long long res = 1e9;
// //这里的i是第一个区间的右端点
// for(int i = 1;i<n;i++){
// //删除掉以i作为右区间第一个数字的情况
// for(int j = i;j<=n;j++){
// // auto p = s.find(a[j]-a[i-1]);
// // s.erase(p);
// auto k = a[j] - a[i-1];
// s.erase(s.find(k));
// }
// //这里的j是第一个区间的左端点
// for(int j = 1;j<=i;j++){
// auto k = a[i] - a[j-1];
// //找到又区间中最接近k的位置,用lower_bound(s.begin(),s.end(),k)
// //会慢很多,不建议
// auto p = s.lower_bound(k);
// if(p!=s.end()){
// res = minn(res,abs(*p-k));
// }
// if(p!=s.begin()){
// p--;
// res = minn(res,abs(*p-k));
// //lower_bound返回的是第一个>=k的数字,因此绝对值最小的情况也可能在p前面一点
// }
// }
// }
// cout<<res<<endl;
// return 0;
// }