codeforces 357div2总结

A B题水题 思维不够活想的太久

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
set<int>st;
int n,b,c;
string a;
int main()
{
    scanf("%d",&n);
    bool sym = false;
    while(n--)
    {
        cin>>a>>b>>c;
        if(b>=2400&&c>b)sym = true;
    }
    if(sym)printf("YES\n");
    else printf("NO\n");
    return 0;   
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
using namespace std;
set<int>st;
LL n,a[3] = {1234567ll,123456ll,1234ll};
int main()
{
    scanf("%I64d",&n);
    bool sym = false;
    for(LL i=0;;i++)
      {
         if(a[0]*i>n)break;
         LL sum1 = a[0]*i;
         for(LL j=0;;j++)
         {
            if(sum1+j*a[1]>n)break;
            LL sum2 = sum1+j*a[1];
            if((n-sum2)%a[2]==0)sym = true;
         }
    }
    if(sym)printf("YES\n");
    else printf("NO\n");
    return 0;   
}

C题 贪心 + stl
1.removeMin 删掉原有第一个元素若为空加个insert a 语句
2.getMin a 删掉现有比a小的数 并加removeMin语句 结束后如果set里没a加3.a并加insert a语句
insert a set加a
教训 用cin 要解除绑定
判断stl 里最小的数是不是a时要判断容器是否为空因为*se.end()的值未知这个很重要!!!!!!!!!!

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
using namespace std;
multiset<int>st;
int n,b;
string a;
struct node{
    string str;
    int va;
}no1;
queuequ;
int main()
{
    ios::sync_with_stdio(false); 
    cin>>n;

    for(int i=0;iset<int>::iterator it1,it2,it3;
        cin>>a;
        if(a=="insert")
        {  
           cin>>b;
           no1.str = a;
           no1.va = b;
           qu.push(no1);
           st.insert(b);    
        }
        else if(a=="getMin")
        {
            cin>>b;
            it2 =  st.lower_bound(b);


            for(it1 = st.begin();it1!=it2;++it1)
                {

                    no1.str = "removeMin";
                    no1.va = *it1;
                    qu.push(no1);

                }
            st.erase(st.begin(),it2);

            if(*(st.lower_bound(b))!=b||st.size()==0)//这里注意判空
            {
                st.insert(b);
                no1.str = "insert";
                no1.va = b;
                qu.push(no1);
            }

           no1.str = a;
           no1.va = b;
           qu.push(no1);
        }
        else
        {
           if(st.size())
           {
             no1.str = a;
             no1.va = *st.begin();
             qu.push(no1);
             st.erase(st.begin());
           }
           else{
             no1.str = "insert";
             no1.va =   -100000000;
             qu.push(no1);
             no1.str = a;
             qu.push(no1);
           }
        }   
    }
    cout<while(qu.size())
    {
        no1 = qu.front();
        cout<if(no1.str!="removeMin")
        {
            cout<<" "<cout<return 0;   
}

D题
优先队列+dfs
从祖先往子节点推
先把子节点的喜欢送礼物的人写入列表并把这些人按辈分排序(优先队列)记录此时加入列表的最大辈分
如果推到某个节点此时列表的最大辈分大于这个节点想送礼物的人的辈分
或列表的最大辈分和这个节点想送礼物的人的辈分都大于这个节点的辈分则没有可行解,否则继续dfs
教训
1.思维不行很多小点考虑不到
2.dfs练得太少

#include
#include
#include
#include
#include
#include
#include
using namespace std;
int next1[110000],last[110000],edge[110000],va[110000] = {0},am[110000] = {0},co2[110000] = {0};
int n,m,co[110000] = {0},sym = true,maxx = 1100000,l = 0,ans = 0;

struct node{
    int x,y;
    bool operator<(node a)const
    {
        return ybool operator>(node a)const
    {
        return y>a.y;
    }
}no1;
priority_queuequ;

int dfs(int ro,int pre,int maxx)
{
   co[ro] = pre;
   int pre2 = 1100000;
   for(int i=last[ro];i!=-1;i = next1[i])
           pre2 = min(pre2,dfs(edge[i],pre+1,maxx));    
    maxx = pre2;
    if(co[va[ro]]<=maxx&&maxx>=co[ro]||co[va[ro]]==maxx)
    {
       if(!co2[va[ro]])
       {
         no1.x = va[ro];
         no1.y = co[va[ro]];
         qu.push(no1);
         co2[va[ro]] = 1;
         ans++;
       }
       maxx = co[va[ro]];
    }
    else sym = false;
    return maxx;    
}


void add(int a,int b)
{
     edge[l] = b;
     next1[l] = last[a];
     last[a] = l;
     l++;
}


int main()
{
    scanf("%d%d",&n,&m);
    memset(next1,-1,sizeof(next1));
    memset(last,-1,sizeof(last));
    while(m--)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        am[b]++;
        add(a,b);
    }
    for(int i=1;i<=n;i++)
        scanf("%d",&va[i]);
    for(int i=1;i<=n;i++)
        if(!am[i])int ha = dfs(i,0,1100000);
    if(sym)
    {
        printf("%d\n",ans);
        while(qu.size())
        {
            no1 = qu.top();
            printf("%d\n",no1.x);
            qu.pop();
        }
    }
    else printf("-1\n");
    return 0;
}

E题 很坑的几何
把每个圆和目标圆的可行角度区间求出来
如果目标圆圆心在某个圆内输出1.0000000结束程序
把区间合并求出总弧度即可

教训
1.数学太差高中几何玩的实在太烂
2.注意不要爆long long
3.在表达式不爆long long 的同时double运算尽量换为整形运算防止精度误差

#include
#include
#include
#include
#include
#include
#define LL long long

using namespace std;

vector< pair<double,double> >ve;
LL xx,yy,r0,v,t,n;

bool cmp(pair<double,double> a,pair<double,double> b)
{
    if(fabs(a.first-b.first)<=1e-9)return a.secondreturn a.firstint main()
{
    scanf("%I64d%I64d%I64d%I64d",&xx,&yy,&v,&t);
    r0 = v*t;
    scanf("%I64d",&n);
    double ans = 0.0;
    bool sym = true;
    while(n--)
    {
        LL x1,y1,r1;
        scanf("%I64d%I64d%I64d",&x1,&y1,&r1);
        if(!sym)continue;
        double dis = sqrt(((double)x1-xx)*(x1-xx)+(y1-yy)*(y1-yy));
        if((x1-xx)*(x1-xx)+(yy-y1)*(yy-y1)<=r1*r1)//圆心在圆内
        {
            ans = 1.0;
            printf("%f\n",ans);
            sym = false;
            continue;
        }

        if((double)r1+r0<=dis)continue;//无相交弧度

        double angle = acos((x1-xx)/dis),range;
        if(y1-yy<=0)
        {
            angle = -angle; 
            angle += 2*acos(-1.0);
        }
        LL a1 = (x1-xx)*(x1-xx)+(yy-y1)*(yy-y1),b1 = r1*r1;
        if(a1-b1<=(double)r0*r0)
        {
          range = asin(1.0*r1/dis);
        }
        else range = acos((dis*dis+r0*r0-r1*r1)/(2*dis*r0));
        double l = angle - range,r = angle + range;//求弧度范围易出错

        if(l<0.0)//边界弧度分解易于下面弧度区间合并
        {
          l+=2*acos(-1.0);
          ve.push_back(make_pair(l,2*acos(-1.0)));
          ve.push_back(make_pair(0.0,r));
        }
        else if(r>2*acos(-1.0))
        {
          r-=2*acos(-1.0);
          ve.push_back(make_pair(l,2*acos(-1.0)));
          ve.push_back(make_pair(0.0,r));
        }
        else ve.push_back(make_pair(l,r));
    }

    if(sym)
    {
        double ans = 0.0,pre = 0.0;//求总弧度
        sort(ve.begin(),ve.end(),cmp);
        for(int i=0;idouble preL = ve[i].first,preR = ve[i].second;
            if(preR>pre)
            {
               ans+=preR-max(pre,preL);
               pre = preR;
            }
        }
        printf("%f\n",ans/(2*acos(-1.0)));
    }

    return 0;
}

你可能感兴趣的:(cf悲剧掉分之路)