模拟赛1补题报告
李智航
S13494
一、题目报告
比赛中第一80分,第二题0分,第三题10分,第四步10分;比赛后全部AK
二、赛中概况
做第一题时,把范围看反了,直接打了一个接近O(n4)的一个代码。然后后两个样例超时。第二题直接把109个数打出来,然后爆了。第三题与第四题直接没时间,没多想,直接打了一个最简单的输出就结束了。
三、解题报告
1.交替出场(alter)
1.题目:题目描述
2.开始代码如下:
#include<bits/stdc++.h>
using namespace std;
int main(){
freopen("alter.in","r",stdin);
freopen("alter.out","w",stdout);
string a;
cin>>a;
int n=a.length();
int ans=n;
int num=1;
int a1[100001];
while(num<n){
for(int i=0;i<n;i++){
bool f=true;
memset(a1,-1,sizeof(a1));
int j=i+num;
if(j<n){
for(int k=i;k<=j;k++){
a1[k]=a[k]-'0';
}
}
for(int k=i;k<=j;k++){
if(a1[k]==a1[k+1]){
f=false;
}
}
if(f==true){
ans++;
}
}
num++;
}
cout<<ans;
fclose(stdin);
fclose(stdout);
return 0;
}
思路:num枚举位数,i为前指针,j为尾指针,将a转化为int类型的a1数组,然后挨个位数比较是否相同,不同计数器就加1,(单子串直接加进累加器)
3.正解
代码如下:
#include<bits/stdc++.h>
using namespace std;
int main(){
string s;
cin>>s;
s=' '+s;
int cnt=0;
int len=s.length();
for(int i=1;i<=len-1;i++){
cnt++;
for(int j=i+1;j<=len;j++){
if(s[j]+s[j-1]=='0'+'1'){
cnt++;
}
else break;
}
}
cout<<cnt;
return 0;
}
2.翻翻转转(filp)
1.题目:
2.开始思路及代码
开始代码如下:
#include<bits/stdc++.h>
using namespace std;
int main(){
string s="1";
for(int i=0;i<25;i++){
string s1;
for(int j=0;j<s.length();j++){
if(s[j]=='0'){
s1+='1';
}if(s[j]=='1'){
s1+='0';
}
}
s+=s1;
}
int T;
cin>>T;
while(T--){
int x;
cin>>x;
int n=s.length();
cout<<s[x-1];
}
return 0;
}
思路:开始直接枚举到225,但是没考虑到string只能存储33554432个字符,直接爆了运行错误。
3.正解
#include<bits/stdc++.h>
using namespace std;
int x;
void fun(int l,int r,int p){
if(l==x&&r==x){
cout<<(1==p)<<endl;
}
int mid=(l+r)/2;
if(x<=mid){
fun(l,mid,p);
}else{
fun(mid+1,r,~p);
}
}
int main(){
int t;
cin>>t;
while(t--){
cin>>x;
fun(1,1<<30,1);
}
return 0;
}
3.方格取数(square)
1.题目:
2.开始的思路与代码:
#include<bits/stdc++.h>
using namespace std;
int a[1001][1001];
int n,m,k;
int ans;
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];
}
}
for(int i=1,j=1;i<=n,j<=m;i++,j++){
ans+=a[i][j];
}
for(int i=1,j=2;i<=n,j<=m;i++,j++){
ans+=a[i][j];
}
cout<<ans;
fclose(stdin);
fclose(stdout);
return 0;
}
思路:没时间了,直接蒙的,看斜线,最中间的斜线与上面的那条斜线相加得出。(只对了一个样例)
3.正解:
#include<bits/stdc++.h>
using namespace std;
long long a[201][201],dp[201][201][201][2],n,m,k,dx[2]={0,1},dy[2]={1,0},ans=-1e18;
int main(){
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
}
}
memset(dp,-0x3f,sizeof(dp));
dp[1][1][0][0]=dp[1][1][0][1]=a[1][1];
for(int x=1;x<=n;x++){
for(int y=1;y<=m;y++){
for(int l=0;l<k;l++){
for(int d=0;d<=1;d++){
for(int nd=0;nd<=1;nd++){
long long xx=x+dx[nd];
long long yy=y+dy[nd];
if(xx>n||yy>m||xx<1||yy<1){
continue;
}
if(d!=nd){
dp[xx][yy][1][nd]=max(dp[xx][yy][1][nd],dp[x][y][l][d]+a[xx][yy]);
}
else if(l<k-1){
dp[xx][yy][l+1][nd]=max(dp[xx][yy][l+1][nd],dp[x][y][l][d]+a[xx][yy]);
}
}
}
}
}
}
for(int i=0;i<k;i++){
for(int j=0;j<=1;j++){
ans=max(ans,dp[n][m][i][j]);
}
}
if(ans==-1e18){
cout<<"No Answer!";
}
else{
cout<<ans;
}
return 0;
}
4.圆圆中的方方(round)
1.题目:
2.开始代码与思路:
#include<bits/stdc++.h>
using namespace std;
int main(){
freopen("round.in","r",stdin);
freopen("round.out","w",stdout);
int n,m,a,b,r;
cin>>n>>m>>a>>b>>r;
if(n==1&&m==1&&a==0&&b==0&&r==1){
cout<<"0.7853981634";
return 0;
}
else if(r==0){
cout<<"0";
return 0;
}
fclose(stdin);
fclose(stdout);
return 0;
}
思路:(当时已经结束了,在传代码时做的)看了第一个测试点,直接打上;突然一个冷想法,半径为0,但没测试点。
3.前铺思路(知识点)
样例1:白给
样例2:圆包含整个矩形,直接矩形面积
样例3:圆在矩形里,求圆圈的面积
剩下的:)
考虑将整块面积分为四部分,圆心的左上,圆心的左下,圆心的右上,圆心的右下。那么问题将转化为了,一个圆心在角落的 圆与矩形的面积交。
经过一系列对称后可以保证与下图同构。
图1和图四一个是扇形面积(α/2Πrr)
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/4f6b8224b33e4189a2e5f63cb4e75590.png#pic_ce
第二三图就是划三角形与扇形
扇形勾股,然后底边*底边,伞形同上
4.正解
#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1), eps = 1e-6;
double n, m, x, y, r;
double calc(double n, double m, double r) {
if (n > m)
swap(n, m);
if (n < eps || m < eps)
return 0;
if (r <= n)
return 0.25 * pi * r * r;
else if (r <= m) {
double tt = sqrt(r * r - n * n);double res = n * tt / 2.0;double ang = pi / 2 - acos(n / r);
res += ang / 2 * r * r;
return res;
}
else if (r <= sqrt(n * n + m * m)) {
double t1 = sqrt(r * r - n * n), t2 = sqrt(r * r - m * m);double res = n * t1 / 2.0 + m * t2 / 2.0;double ang = pi / 2 - acos(n / r) - acos(m / r);
res += ang / 2 * r * r;
return res;
} else
return n * m;
}
int main() {
cin >> n >> m >> x >> y >> r;
cout << fixed << setprecision(10)<< calc(x, y, r) + calc(x, m - y, r) + calc(n - x, y, r) +calc(n - x, m - y, r)<< endl;
return 0;
}
总结
时间出现了大问题,代码的思路不是很清晰,导致做题是浪费了很多时间,很多问题和细节没考虑到,分数也就随之丢了,