做到自闭系列,这次还算有进步,原来是只会做两道并且只能做对两道别的写都写不出来,这次虽然只对了一道,但是还写出来别的三道,两道对了88%,一道对了30%(看出考点但不会写),反正是蓝桥杯选手,按照这样总分还多了呢,另外那个A题是博弈论,但是这类题没练过,只能吃瘪。
1、Applese 的减肥计划
Applese 最近又长胖了,于是它打算减肥——练习举重。
他在举重的时候用两只手往不同方向用力,从而把杠铃举起来。
已知 Applese 两只手分别产生的力的大小,以及它们之间的夹角,试求两力合力的大小。
输入描述:
仅一行三个整数 f1,f2,a,分别表示两只手产生的力的大小以及它们之间的夹角。
输出描述:
输出一个实数表示两力合力的大小,要求相对误差或绝对误差不超过 10^−6。
严格来讲,如果你的答案是 a,而标准答案是 b,那么当 |a−b|max{1,|b|}≤10−6 时,你的答案会被认为是正确的。
示例1
输入
6 8 90
输出
10.0000000000
示例2
输入
10 10 60
输出
17.3205080757
备注:
1≤f1,f2≤100
0≤a≤180
#include<bits/stdc++.h>
using namespace std;
int main()
{
int f1,f2,x;
const double pi=acos(-1.0);
cin>>f1>>f2>>x;
double ans=sqrt(f1*f1+f2*f2+2*f1*f2*cos(x*pi/180));
printf("%.10lf\n",ans);
return 0;
}
2、Applese走方格
精通程序设计的 Applese 又写了一个游戏。
在这个游戏中,它位于一个 n 行 m 列的方阵中的左上角(坐标为(0, 0),行的序号为,列的序号为)。
现在它想不重复地走过所有格子(除了起点),最后回到左上角的一个方案。
每次只能往上下左右其中一个方向走一格。
输入描述:
仅一行两个整数 n 和 m,表示方阵的大小。保证大于1×1。
输出描述:
如果存在方案,则输出一行操作,包含"L"、“R”、“U”、“D”,分别表示左、右、上、下。如果有多种方案,输出任意一种即可。
如果没有方案,则在一行中输出"-1"。
示例1
输入
2 2
输出
RDLU
示例2
输入
2 3
输出
RRDLLU
备注:
1≤n,m≤10
请允许我问候出题人,这么像搜索的题,你居然给我来了个规律做法?!心态当场爆炸,本来思路是用DFS,便利可能路线,把路线存在堆栈里,再把堆栈倒着输出出来,运行超时,结束后看了看通过了85%的测试用例,肯定是我太菜了,官方做法震惊
85%代码:
#include<bits/stdc++.h>
using namespace std;
int N,M,flag=0,t;
int vis[15][15];
int dir[4][2]={1,0,-1,0,0,1,0,-1};
stack<char> q;
void dfs(int x,int y,int cnt)
{
if(flag) return;
if(t==1&&x==0&&y==0&&cnt==M*N+1)
{
flag=1;
char str[225];
int i=0;
while(!q.empty())
{
str[i]=q.top();
q.pop();
i++;
}
while(i--) cout<<str[i];
cout<<endl;
return;
}
if(t==0&&x==0&&y==0)
{
t=1;
for(int i=0;i<4;i++)
{
int tx=x+dir[i][0];
int ty=y+dir[i][1];
if(tx<0||ty<0||tx>=N||ty>=M) continue;
if(vis[tx][ty]==1&&cnt!=M*N) continue;
vis[tx][ty]=1;
switch(i){
case 0:q.push('D');break;
case 1:q.push('U');break;
case 2:q.push('R');break;
case 3:q.push('L');break;
}
dfs(tx,ty,cnt+1);
vis[tx][ty]=0;
q.pop();
if(flag) return;
}
}
else
{
for(int i=0;i<4;i++)
{
int tx=x+dir[i][0];
int ty=y+dir[i][1];
if(tx<0||ty<0||tx>=N||ty>=M) continue;
if(cnt==N*M&&tx==0&&ty==0)
{
vis[tx][ty]=1;
switch(i){
case 0:q.push('D');break;
case 1:q.push('U');break;
case 2:q.push('R');break;
case 3:q.push('L');break;
}
dfs(tx,ty,cnt+1);
}
if(vis[tx][ty]==1) continue;
vis[tx][ty]=1;
switch(i){
case 0:q.push('D');break;
case 1:q.push('U');break;
case 2:q.push('R');break;
case 3:q.push('L');break;
}
dfs(tx,ty,cnt+1);
vis[tx][ty]=0;
q.pop();
if(flag) return;
}
}
}
int main()
{
cin>>N>>M;
t=0;
memset(vis,0,sizeof(vis));
vis[0][0]=1;
dfs(0,0,1);
if(flag==0)
cout<<"-1"<<endl;
return 0;
}
官方的意思就是根据这个图暴力就好了,败了败了。
官方代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, m;
cin >> n >> m;
if (n == 1)
{
if (m == 2)
cout << "RL" << endl;
else
cout << -1 << endl;
}
else if (m == 1)
{
if (n == 2)
cout << "DU" << endl;
else
cout << -1 << endl;
}
else if (n % 2 == 0)
{
cout << "R";
for (int i = 0; i < n; i += 2)
{
if (i)
cout << "D";
for (int j = 1; j < m - 1; j++)
cout << "R";
cout << "D";
for (int j = 1; j < m - 1; j++)
cout << "L";
}
cout << "L";
for (int i = 0; i < n - 1; i++)
cout << "U";
cout << endl;
}
else if (m % 2 == 0)
{
cout << "D";
for (int i = 0; i < m; i += 2)
{
if (i)
cout << "R";
for (int j = 1; j < n - 1; j++)
cout << "D";
cout << "R";
for (int j = 1; j < n - 1; j++)
cout << "U";
}
cout << "U";
for (int i = 0; i < m - 1; i++)
cout << "L";
cout << endl;
}
else
cout << -1 << endl;
return 0;
}
3、Applese的QQ群
Applese 有一个QQ群。在这个群中,大家互相请教问题。如 b 向 a 请教过问题,就把 a 叫做是 b 的"老板"。这样一个群中就会有很多老板。
同时规定:如果 a 是 b 的老板,b 是 c 的老板,那么 a 也是 c 的老板。
为了不破坏群里面和谐交流的氛围,Applese 定了一个群规:不允许出现 a 既是 b 的老板, b 又是 a 的老板。
你需要帮助 Applese 判断大家是否遵守了群规。
输入描述:
第一行两个整数 n, m,表示群里的人数以及请教问题的数量。
接下来 m 行,每行两个整数 a, b,表示 a 是 b 的"老板",即 b 向 a 请教了一个问题。
注:无论是否违反了群规,a 都会成为 b 的老板。
输出描述:
对于每次提问,输出一行"Yes"表示大家都遵守了群规,反之输出"No"。
示例1
输入
4 4
1 2
2 3
3 1
1 4
输出
Yes
Yes
No
No
备注:
1≤n≤10^5
1≤m≤2⋅10^5
1≤a,b≤n
做的时候一开始以为是并查集,后来发现题目里面有一个也,就是说所有请教过题目的都是老板,实际上应该是图论的知识,找有向图中有没有环,如果有的话就是NO,而且后面就一直是NO,但是技术不够,只能继续假装是并查集做,过了30%的测试用例
30%代码
#include<bits/stdc++.h>
using namespace std;
int peo[10005];
int m,n;
int flag=1;
int find(int x)
{
if(peo[x]==x)
return x;
else
return peo[x]=find(peo[x]);
}
void Union(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx==y||fy==x) flag=0;
if(fx!=fy)
peo[fy]=f x;
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
peo[i]=i;
while(m--)
{
int x,y;
cin>>x>>y;
if(flag)
Union(x,y);
if(flag) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
官方代码:
#include <bits/stdc++.h>
using namespace std;
bool ok(int x, int n, const vector<pair<int, int>>& edges)
{
vector<vector<int>> G(n);
vector<int> deg(n);
for (int i = 0; i < x; i++)
{
G[edges[i].first].push_back(edges[i].second);
++deg[edges[i].second];
}
queue<int> q;
for (int i = 0; i < n; i++)
if (!deg[i]) q.push(i);
int tot = 0;
while (!q.empty())
{
int u = q.front();
q.pop();
++tot;
for (auto& v : G[u])
if (--deg[v] == 0) q.push(v);
}
return tot == n;
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
vector<pair<int, int>> edges;
for (int i = 0, u, v; i < m; i++)
{
scanf("%d%d", &u, &v);
--u, --v;
edges.emplace_back(u, v);
}
int l = 1, r = m, ans;
while (l <= r)
{
int mid = l + r >> 1;
if (ok(mid, n, edges))
l = mid + 1, ans = mid;
else
r = mid - 1;
}
for (int i = 0; i < ans; i++) puts("Yes");
for (int i = ans; i < m; i++) puts("No");
}
4、Applese的回文串
自从 Applese 学会了字符串之后,精通各种字符串算法,比如……判断一个字符串是不是回文串。
这样的题目未免让它觉得太无聊,于是它想到了一个新的问题。
如何判断一个字符串在任意位置(包括最前面和最后面)插入一个字符后能不能构成一个回文串?
输入描述:
仅一行,为一个由字母和数字组成的字符串 s。
输出描述:
如果在插入一个字符之后可以构成回文串,则输出"Yes", 否则输出"No"。
示例1
输入
applese
输出
No
示例2
输入
java
输出
Yes
备注:
|s|≤10^5
这题目实际并不难,如果研究了上上次复读机那个题这个题就有思路,填一个构成回文和删掉一个构成回文是一个意思,如果删掉一个之后是回文,那么在原来位置的对称处补一个就能构成回文了,思维定势了,沿用了上次复读机的思路,导致超时,过了88%的测试用例,吐血
88%代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int p,i,flag=1;
string str;
cin>>str;
string s;
for (int k=0;k<str.length();k++)
{
string s="";
for (int m=0;m<str.length();m++)
if (m!=k) s.push_back(str[m]);
flag=1;
for(int i=0;i<=s.length()/2;i++)
{
if(s[i]!=s[s.length()-i-1])
{
flag=0;
break;
}
}
if(flag) break;
}
if(flag==1) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
return 0;
}
官方代码
#include <bits/stdc++.h>
using namespace std;
int check(const string& s)
{
int n = s.length();
for (int i = 0; i < n; i++)
if (s[i] != s[n - 1 - i])
return i;
return -1;
}
int main()
{
string s;
cin >> s;
int diff = check(s);
if (diff == -1)
cout << "Yes" << endl;
else
{
string tmp = s;
string s1 = s.erase(diff, 1);
string s2 = tmp.erase(tmp.length() - 1 - diff, 1);
if (check(s1) == -1 || check(s2) == -1)
cout << "Yes" << endl;
else
cout << "No" << endl;
}
return 0;
}