日期:2024.10.2
学号:S06465
一:
总分数:
T1【交替出场 (alter)】:100
T2【翻翻转转(filp)】:0
T3【方格取数(square)】:70
T4【圆圆中的方方(round)】:20
二、比赛过程
第一题比较简单,为了保险,我用O(n^2)的思路做的
第二题做的时候没有思路,直接看的后面的题
第三题用的dp,基本上一直在挑错,修改
第四题根本不会,直接输出了样例偏分
三、比赛分析
T1【交替出场 (alter)】:
1.题目大意
给你一个字符串,让你求出字符串中01交替字串的个数
2.比赛中的思考
一层循环枚举左端点,第二层循环从左端点开始遍历,如果当前这一个字符和上一个相等,就跳出循环,否则就让计数器++,最后输出计数器
3.解题思路
枚举左端点,一位一位向右扩展判断
4.AC代码
#include<bits/stdc++.h>
using namespace std;
string s;
int ans;
int main(){
cin>>s;
int len=s.size();
for(int i=0;i<len;i++){
ans++;
for(int j=i+1;j<len;j++){
if(s[j]!=s[j-1]){
ans++;
}
else{
break;
}
}
}
printf("%d",ans);
return 0;
}
T2【翻翻转转(filp)】:
1.题目大意
有一系列的字符串,s[i]是s[i-1]逐位取反后拼接在s[i-1]后的串,求无穷大的字符串中第x个字符是什么
2.比赛中的思考
比赛中没什么想法,直接放弃了
3.解题思路
用二分去做,每次分成两半,如果在左边就保持不变,如果在右边就取反1变0,0变1
4.AC代码
#include<bits/stdc++.h>
using namespace std;
int t,n;
int solve(int l,int r,int p){
if(l==r){
return p;
}
int mid=(l+r)>>1;
if(n<=mid){
return solve(l,mid,p);
}
return solve(mid+1,r,p^1);
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
printf("%d\n",solve(1,1<<30,1));
}
return 0;
}
1.题目大意
从(1,1)出发,走到(n,m),只能向右或者向下走,但是不能不能一次性往一个方向走大于等于k步,问收集到的数字的和的最大值
2.比赛中的思考
我用dp做,考虑是从哪个方向来的,和上一步是向哪走的,把两种方案都存下来
3.解题思路
用记忆化搜索会简单一些,x,y表示当前的位置,step表示连续走了几步,d表示我向哪走,然后根据两种情况(1.继续向这个走,2.向另一个方向走)dfs
4.AC代码
#include<bits/stdc++.h>
using namespace std;
const int N=205;
int n,m,k;
int a[N][N];
int dx[]={0,1};
int 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(){
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&a[i][j]);
}
}
int tmp=max(dfs(1,2,2,0),dfs(2,1,2,1));
if(tmp>-1e9){
printf("%d",tmp+a[1][1]);
}
else{
printf("No Answer!");
}
return 0;
}
T4【圆圆中的方方(round)】:
1.题目大意
你有一个矩形。有一点 A(a,b),求以A为圆心,半径为r的圆与矩形的重叠部分的面积。
2.比赛中的思考
不知道怎么去做,直接输出了输出样例偏分
3.解题思路
可以把圆根据圆心分成四部分,在考虑每部分的情况,第一种情况是r<=n&&r<=m,第四种情况是完全重合,这两种直接计算就行,第二种情况是r>=m&&r<=n,第三种是r>=m&&r>=n但是没有完全重合的情况,这两种情况可以分成几部分并根据三角函数计算
4.AC代码
#include<bits/stdc++.h>
using namespace std;
const double pi=acos(-1),eps=1e-8;
double n,m,a,b,r;
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(){
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;
}