前言
本场考试比较脑残 题目比较新颖
题目分别是
交替出场(alter)
翻翻转转(filp)
方格取数(square)
圆圆中的方方(round)
第一题 交替出场(alter)
题目描述
你有一个四个边界点为 (0,0)(0,0),(n,0)(n,0),(0,m)(0,m),(n,m)(n,m) 的矩形。
有一点 A(a,b)A(a,b),保证 AA 在矩形内部或边界上,求以 AA 为圆心,半径为 rr 的圆与矩形的重叠部分的面积。
输入描述
一行五个浮点数,n,m,a,b,rn,m,a,b,r,含义见题目描述。
输出描述
一行一个浮点数,表示答案
样例输入
0101
样例输出
10
样例解释
显然的,任意一个子串都是 01
交替子串。
数据范围
定义 nn 为字符串 ss 的长度。
对于 20%20% 数据:1≤n≤31≤n≤3。
对于另外 60%60% 数据:1≤n≤1001≤n≤100。
对于全部数据:1≤n≤10001≤n≤1000。
解释
本题就是用当前这一位字符和上一位字符进行比较
AC代码
#include<bits/stdc++.h>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<utility>
#include<cstdlib>
#define ll long long
#define pii pair<long long,long long>
#define endl "\n"
using namespace std;
int cnt;
string s;
int main(){
cin >> s;
int len = (int)s.size();
for(int i = 0;i < len;i++){
//任意的长度为 1 的字符串也被定义为 01 交替串,cnt要加上长度为 1 字符串数量
cnt++;
for(int j = i+1;j < len;j++){
//01 交替串的定义是,前一位必须不同于后一位的字符串,所以 s[j] 不能等于 s[j-1]
if(s[j] != s[j-1]){
cnt++;
}else{
break;
}
}
}
cout << cnt;
return 0;
}
第二题翻翻转转(filp)
题目描述
gza 有一系列的字符串,第 ii 个名为 sisi。
s0=1s0=1
s1=10s1=10
s2=1001s2=1001
s3=10010110s3=10010110
⋯⋯
sisi 是 si−1si−1 逐位取反后拼接在 si−1si−1 后的串。
你需要求 s114514s114514 的第 xx 个字符是什么。
多测。
输入描述
第一行一个整数 TT,表示数据组数。
接下来 TT 行,一行一个整数,表示 xx,含义见题目描述。
输出描述
一共 TT 行,一行一个字符,表示答案。
输入样例
1
3
输出样例
0
数据范围
对于 10%10% 的数据:x≤100x≤100。
对于另外 50%50% 的数据:x≤107x≤107。
对于全部数据:x≤109x≤109。
解释
本题数据范围是2^114514 很明显这是和无穷大差不多的 是不能用打暴力枚举的
本题思路是二分 是因为总长一定是偶数并且前半和后半是相反的 所以如果x在前半直接输出 如果在后半就取反输出
AC代码
#include<bits/stdc++.h>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<utility>
#include<cstdlib>
#define ll long long
#define pii pair<long long,long long>
#define endl "\n"
using namespace std;
int x;
int solve(int L,int R,int p){
if(L==R) return p;
int mid=L+R>>1;
if(x<=mid) return solve(L,mid,p);
return solve(mid+1,R,p^1);
}
int main(){
/*freopen("filp.in","r",stdin);
freopen("filp.out","w",stdout);*/
int t;
cin>>t;
for(int i=0;i<t;i++){
cin>>x;
cout<<solve(1,1<<30,1)<<endl;
}
return 0;
}
第三题方格取数(square)
题目描述
想必大家都做过方格取数吧。
现在,你需要做一个特殊的方格取数。
每个格子都有一个数字,走过便能收集,也必须收集。
你从 (1,1)(1,1) 出发,目标是 (n,m)(n,m),只能向右或者向下走,但是你不能一次性往一个方向走大于等于 kk 步。
求收集到的数字的和的最大值。
如果无解,输出 No Answer!
。
输入描述
第 11 行三个正整数 n,m,kn,m,k。
接下来 nn 行每行 mm 个整数,依次代表每个方格中的整数。
输出描述
一个整数,表示收集到的数字的和的最大值。
输入样例1
3 3 2
1 1 1
1 1 2
1 1 1
输出样例1
6
输入样例2
3 3 2 1 1 2 1 1 1 2 1 1
输出样例2
5
数据范围
对于 50%50% 数据:n,m,k≤5n,m,k≤5
全部数据下:n,m,k≤200,∣ai,j∣≤105n,m,k≤200,∣ai,j∣≤105
解释
本题用四维DP分别是坐标,坐标,步数,方向,并且采用pair来记录走没走过也就是vis
AC代码
#include<bits/stdc++.h>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<utility>
#include<cstdlib>
#define ll long long
#define pii pair<long long,long long>
#define endl "\n"
using namespace std;
const int N=201;
int n,m,k,a[N][N];
int dx[]={0,1},dy[]={1,0};
pair<int,bool> f[N][N][N][2];
int dfs(int x,int y,int step,int d){
if(x>n||y>m||step>k) return -0x3f3f3f3f;
if(x==n&&y==m){
return a[x][y];
}
if(f[x][y][step][d].second) return f[x][y][step][d].first;
f[x][y][step][d].second=1;
int ans=-0x3f3f3f3f;
if(step<k) ans=max(ans,dfs(x+dx[d],y+dy[d],step+1,d));
ans=max(ans,dfs(x+dx[d^1],y+dy[d^1],2,d^1));
if(ans<-1e9) return f[x][y][step][d].first=-0x3f3f3f3f;
return f[x][y][step][d].first=ans+a[x][y];
}
int main(){
/*freopen("square.in","r",stdin);
freopen("square.out","w",stdout);*/
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
}
}
int tmp=max(dfs(1,2,2,0),dfs(2,1,2,1));
if(tmp>-1e9) cout<<tmp+a[1][1];
else cout<<"No Answer!";
return 0;
}
第四题圆圆中的方方(round)
题目描述
你有一个四个边界点为 (0,0)(0,0),(n,0)(n,0),(0,m)(0,m),(n,m)(n,m) 的矩形。
有一点 A(a,b)A(a,b),保证 AA 在矩形内部或边界上,求以 AA 为圆心,半径为 rr 的圆与矩形的重叠部分的面积。
输入描述
一行五个浮点数,n,m,a,b,rn,m,a,b,r,含义见题目描述。
输出描述
一行一个浮点数,表示答案。
样例输入
1 1 0 0 1
样例输出
0.7853981634
数据范围
设答案为 aa,输出为 bb。
若 ∣a−b∣max(1,b)≤10−4max(1,b)∣a−b∣≤10−4,则给予这个测试点的分数。
对于测试点 11,保证数据同样例。
对于测试点 22,保证 r≥n2+m2r≥√n2+m2。
对于测试点 33,保证 r≤min(a,b,n−a,m−b)r≤min(a,b,n−a,m−b)。
对于测试点 44∼66,保证 n,m,a,b,r≤10n,m,a,b,r≤10。
对于测试点 77,保证 a=b=0a=b=0。
对于所有测试点,保证 n,m,a,b,r≤104,0≤a≤n,0≤b≤mn,m,a,b,r≤104,0≤a≤n,0≤b≤m。
解释
本题涉及三角函数等初三数学,总共需要四种分类,可以将长方形分成四份,将圆心放在坐下,然后拆分,分解成多个图形后求面积
AC代码
#include<bits/stdc++.h>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<utility>
#include<cstdlib>
#define ll long long
#define pii pair<long long,long long>
#define endl "\n"
using namespace std;
double n,m,a,b,r,p=3.1415926;
const double pi =acos(-1),eps=1e-8;
double cal(double n,double m,double r){
if(n<m) swap(n,m);
if(n<=eps||m<=eps) return 0;
if(r<=m) return 0.25*pi*r*r;
if(r>=sqrt(n*n+m*m)) return n*m;
if(r<=n) return sqrt(r*r-m*m)*m*0.5+0.5*r*r*(0.5*pi-acos(m/r));
return sqrt(r*r-m*m)*m*0.5+sqrt(r*r-n*n)*n*0.5+0.5*r*r*(0.5*pi-acos(m/r)-acos(n/r));
}
int main(){
/*freopen("round.in","r",stdin);
freopen("round.out","w",stdout);*/
cin>>n>>m>>a>>b>>r;
printf("%lf",cal(a,b,r)+cal(n-a,b,r)+cal(a,m-b,r)+cal(n-a,m-b,r));
return 0;
}