Codeforces1600分训练日记

2019/5/22

1700 \color{red}1700 1700 模 拟 \color{purple}模拟

题意主要是要求两种二维坐标的转换;简单的题目,就是暴力转换就可以了
我们需要考虑的就是判断是哪一种形式,通过在字母后出现了字符,在字符后又一次出现了字母的方式。需要注意的是转换BBC这样的形式的时候,通过进制转换%26进行,但是需要考虑=0的时候应该是Z,而Z需要占用一个26,所以/=26之后的结果需要-1

By zylzyl, contest: Codeforces Beta Round #1, problem: (B) Spreadsheet, Accepted, #
 #include<bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
using namespace std;

#define ll long long

string str;

int n,x,y;

bool check(){
    int index;
    for(int i=1;i<str.size();i++){
        if(str[i]>='0'&&str[i]<='9'){
            index = i;
            break;
        }
    }
    for(int i=index+1;i<str.size();i++){
        if(str[i]>='A'&&str[i]<='Z')return false;
    }
    return true;
}

int main(){
    cin>>n;
    FOR(i,1,n){
        cin>>str;
        x=0,y=0;
        if(check()){
            int k=0;
            while(!isdigit(str[k])&&k<str.size()){
                y=y*26+(str[k]-'A'+1);
                k++;
            }
            while(k<str.size()){
                x=x*10+(str[k]-'0');
                k++;
            }
            cout<<"R"<<x<<"C"<<y<<endl;
        }
        else{
            int k=1;
            while(str[k]!='C'&&k<str.size()){
                x=x*10+(str[k]-'0');
                k++;
            }
            k++;
            while(k<str.size()){
                y=y*10+(str[k]-'0');
                k++;
            }
            string st="";
            while(y){
                if(y%26!=0)
                st+='A'+y%26-1;
                else st+='Z',y--;
                y/=26;
            }
            for(int i=st.size()-1;i>=0;i--)
                printf("%c",st[i]);
            cout<<x<<endl;
        }
    }
}
2100 \color{red}2100 2100 数 学 \color{purple}数学

题意是给出正n边形的三个点,去求最小正n边形的面积。
考虑正n边形的外接圆,三个点都在圆上。三个点可以构成一个三角形。每两个点和正n变形的中心可以构成一个扇形,我们可以了解到,只要求到正n边形的最小扇形即可
我们首先计算三条边的距离:a,b,c;面积用海伦公式计算:
p = a + b + c 2 p=\frac{a+b+c}{2} p=2a+b+c
S = p ∗ ( p − a ) ∗ ( p − b ) ∗ ( p − c ) S=\sqrt{p*(p-a)*(p-b)*(p-c)} S=p(pa)(pb)(pc)

首先对于这些扇形的圆心角,一定是最小圆心角的倍数,可以通过求两个圆心角之间的最小公倍数求出最小圆心角。
*对于扇形对应的三角形,利用余弦定理可以求解出圆心角: cos ⁡ A = b ∗ b + c ∗ c − a ∗ a 2 ∗ a ∗ c \cos A = \frac{b*b+c*c-a*a}{2*a*c} cosA=2acbb+ccaa
为了保证精确度,求出两个圆心角,直接用 2 π 2\pi 2π减去得到第三个圆心角
面积公式: s = sin ⁡ θ ∗ r ∗ r 2 s=\frac{\sin \theta *r*r}{2} s=2sinθrr
正弦定理: sin ⁡ A a = sin ⁡ B b = sin ⁡ C c = 1 2 ∗ r \frac{\sin A}{a}=\frac{\sin B}{b}=\frac{\sin C}{c}=\frac{1}{2*r} asinA=bsinB=csinC=2r1这里的r为外接圆半径
r = a 2 sin ⁡ A r=\frac{a}{2\sin A} r=2sinAa
s = 1 2 b c sin ⁡ A s=\frac{1}{2}bc\sin A s=21bcsinA
推导得到: r = a b c 4 s r=\frac{abc}{4s} r=4sabc
这样我们可以求出外接圆半径,从而可以用余弦定理求出圆心角,利用fgcd()求出最小圆心角。
求fmod的时候注意eps尽量较大,否则误差会很大

#include<bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
using namespace std;

#define ll long long
#define eps 1e-4
#define PI acos(-1.0)
string str;

struct Point{
    double x,y;
};

double gcd(double a,double b)
{
	if(b+eps>0&&b-eps<0)
		return a;
	if(a+eps>0&&a-eps<0)
		return b;
	return gcd(b,fmod(a,b));
}

int main(){
    Point a,b,c;
    double A,B,C;
    scanf("%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y);
    double al=sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    double bl=sqrt((a.x-c.x)*(a.x-c.x)+(a.y-c.y)*(a.y-c.y));
    double cl=sqrt((b.x-c.x)*(b.x-c.x)+(b.y-c.y)*(b.y-c.y));
    double p=(al+bl+cl)/2;
    double S=sqrt(p*(p-al)*(p-bl)*(p-cl));
    double R=(al*bl*cl)/(4*S);
    A=acos((R*R+R*R-al*al)/(2.0*R*R));
    B=acos((R*R+R*R-bl*bl)/(2.0*R*R));
    C=2*PI-A-B;
    double angle=gcd(A,gcd(B,C));
    //cout<<A<<" "<<B<<" "<<C<<endl;
    double ans;
    //cout<<A<<" "<<B<<" "<<C<<endl;
    ans=sin(angle)*0.5*R*R*(2*PI/angle);
    printf("%.6lf\n",ans);
}

2019/5/23

1600 \color{red}1600 1600 模 拟 \color{purple}模拟

题意是求解最后分数最大的人,如果有相同分数的就选先到达最大分数的人。分数不断累加。
我的想法先用map记录每个人的分数,求出最大,再重新遍历一遍,这时候只考虑最大的人,先到达的先输出

#include<bits/stdc++.h>
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;

int n;
string A[1010];
int B[1010];
map<string,int>M,T;


int main(){
    cin>>n;
    FOR(i,1,n){
        cin>>A[i]>>B[i];
        M[A[i]]+=B[i];
    }
    int ans=-1;
    for(map<string,int>::iterator iter=M.begin();iter!=M.end();iter++){
        ans=max(ans,(*iter).second);
    }
    int res;
    FOR(i,1,n){
        if(M[A[i]]==ans){
            T[A[i]]+=B[i];
            if(T[A[i]]>=ans){
                cout<<A[i]<<endl;
                break;
            }
        }
    }
}
2000 \color{red}2000 2000 D P \color{purple}DP DP

题意:只能往下和往右走,每个走到这个格子乘上这个格子的数,使得最小结果的后缀0尽可能地少
这种无后效性地优先考虑DP,向下和向右真的是完美DP了,但是如果使得这一步到下一步的后缀0最小呢,事实上如果 a = 2 ∗ 2 ∗ 2 ∗ 3 a=2*2*2*3 a=2223 b = 5 ∗ 5 ∗ 3 b=5*5*3 b=553一定是两个0,因为2和5可以组成一个0,而且考虑到最后都是2和5组成的0, 4 ∗ 5 = 2 ∗ 2 ∗ 5 4*5=2*2*5 45=225
所以我们预处理出每个数2和5的个数,走两遍dp,最后选最小的
但是要求返回路径,直接用递归,判断能不能符合dp转移即可
还需要考虑的是0的情况,如果含0,那么标记一下,0相当于结果是1,如果ans>1的话可以直接选择0,暴力走到0再走到重点即可

#include<bits/stdc++.h>
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;

int n;
int A[1010][1010],B[1010][1010][2];
int dp[1010][1010][2];

void Pri(int i,int j,int x){
    int f=3;
    if(i-1>=1&&dp[i-1][j][x]+B[i][j][x]==dp[i][j][x])Pri(i-1,j,x),f=1;
    else if(j-1>=1&&dp[i][j-1][x]+B[i][j][x]==dp[i][j][x])Pri(i,j-1,x),f=2;
    //printf("dp[%d][%d][%d](%d)+B[%d][%d][%d](%d)=dp[%d][%d][%d](%d)\n",i-1,j,x,dp[i-1][j][x],i,j,x,B[i][j][x],i,j,x,dp[i][j][x]);
    //printf("dp[%d][%d][%d](%d)+B[%d][%d][%d](%d)=dp[%d][%d][%d](%d)\n",i,j-1,x,dp[i][j-1][x],i,j,x,B[i][j][x],i,j,x,dp[i][j][x]);
    if(f==3)return ;
    if(f==1)printf("D");
    else printf("R");
}

int main(){
    cin>>n;
    memset(dp,0x3f,sizeof(dp));
    memset(A,0,sizeof(A));
    memset(B,0,sizeof(B));
    FOR(i,1,n)FOR(j,1,n)scanf("%d",&A[i][j]);
    int ans,flag=0,_x,_y;
    FOR(i,1,n)FOR(j,1,n){
        int x=A[i][j],y=A[i][j];
        if(!x){
            flag=1;
            _x=i,_y=j;
            B[i][j][0]++,B[i][j][1]++;
            continue;
        }
        while(x&&x%2==0){
            x/=2;
            B[i][j][0]++;
        }
        while(y&&y%5==0){
            y/=5;
            B[i][j][1]++;
        }
    }
    dp[1][1][0]=B[1][1][0];
    dp[1][1][1]=B[1][1][1];
    FOR(i,1,n)FOR(j,(i==1?2:1),n){
        if(i-1>=1)dp[i][j][0]=min(dp[i][j][0],dp[i-1][j][0]);
        if(j-1>=1)dp[i][j][0]=min(dp[i][j][0],dp[i][j-1][0]);
        dp[i][j][0]+=B[i][j][0];
        if(i-1>=1)dp[i][j][1]=min(dp[i][j][1],dp[i-1][j][1]);
        if(j-1>=1)dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][1]);
        dp[i][j][1]+=B[i][j][1];
    }
    ans=min(dp[n][n][0],dp[n][n][1]);
    if(ans>1&&flag){
        puts("1");
        int __x=1,__y=1;
        while(__x<_x)__x++,cout<<'D';
        while(__y<_y)__y++,cout<<'R';
        while(__y<n)__y++,cout<<'R';
        while(__x<n)__x++,cout<<'D';
    }
    else{
        cout<<ans<<endl;
        if(dp[n][n][0]<dp[n][n][1]){
            Pri(n,n,0);
        }
        else{
            Pri(n,n,1);
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用的内容,CodeForces的初始由1500改为了1400,并且前六场的初始配如下:第一场500,第二场350,第三场250,第四场150,第五场100,第六场50。所以,根据你在第一场的表现为368,你的总应为868(1400+368)。接下来的五场比赛,你的表现将根据具体情况来决定。每场比赛的表现会对你的总产生影响。 关于其他引用和的代码,它们似乎是一些针对不同情况进行计算和输出的算法,并不直接涉及到CodeForces上的数计算。所以,如果你有关于CodeForces上的具体问题,请提供更多详细信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [CodeForces前六场定级赛赋规则(2020.5修订)及各段位对应数段](https://blog.csdn.net/Sunshine_xiaohao/article/details/112106625)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [CodeForces上日记 (思维题)(A. Garland)1809A (Educational Round 145 For Div.2)](https://blog.csdn.net/weixin_60375636/article/details/130243342)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [【codeforces】一切为了上:骚操作合集](https://blog.csdn.net/weixin_45497996/article/details/109157711)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值