1.4 SMU Winter 2023 Round #1 (Div.2)

思路:比较大小
 
if(x>y)cout<<"NO";
    else if(x<y)cout<<"YES";
    else cout<<"equal probability";

 

 思路:n的各位数字和的值,平方,立方
 while(n){
        s+=n%10;
        n/=10;
    }
    cout<<s<<'\n'<<s*s<<'\n'<<s*s*s;

 

 
思路:先判断H,再判断D,S,最后判断C
关键点:

1. 集齐16张牌便可以加1000

2. 集齐13张红桃加200

3. 若所有红桃牌不在同一个人的手中,那么分值按照:

4. −50,−2,−3,−4,−5,−6,−7,−8,−9,−10,−20,−30,−40来计算。

5. 猪牌和羊牌分别为100和100

6. 集齐13张红桃、羊牌和猪牌,加500分

7. 若除了C10还有其他计分牌则将其他计分牌的分数*2

 
 
int n,sum[10005][17],number;
int Fs[17]={0,-50,-2,-3,-4,-5,-6,-7,-8,-9,-10,-20,-30,-40,-100,100};
char s;

//所有牌和为0则结束
int Tot=0,ans=0;
        memset(sum,0,sizeof(sum));
        for(int i=1;i<=4;i++){
            cin>>n;
            Tot+=n;
            for(int j=1;j<=n;j++){
                cin>>s>>number;
                if(s=='H')sum[i][number]=1;
                if(s=='S')sum[i][14]=1;
                if(s=='C')sum[i][16]=1;
                if(s=='D')sum[i][15]=1;
            }
        }
        if(Tot==0)return 0;

//ok判断h是否在一家
for(int i=1;i<=4;i++){
            int ok=1;
            ans=0;
            for(int j=1;j<=13;j++)
                if(sum[i][j]==0){
                    ok=0;
                    break;
                }
            if(ok){
                if(sum[i][14]&&sum[i][15])ans+=500;
                else ans+= 200 + ((sum[i][14]) ? 1 : 0) * Fs[14]+((sum[i][15])?1:0)*Fs[15];
                if(sum[i][16])ans*=2;
                if(ans > 0)printf("+%d ", ans);
                else printf("%d ", ans);
            }
            else{
                ok=1;
                for(int j=1;j<=15;j++)
                    if(sum[i][j]){
                        ok=0;
                        break;
                    }
                if(ok==1){
                    if(sum[i][16])printf("+50 ");
                    else printf("0 ");
                }
                else{
                    for(int j=1;j<=15;j++)ans+= ((sum[i][j]) ? 1 : 0)* Fs[j];
                    if(sum[i][16])ans*=2;
                    if(ans > 0)printf("+%d ", ans);
                    else printf("%d ", ans);
                }
            }
        }
cout<<'\n';
 
思路:满足 1+2+...+i <=n 的最大前缀和,依次输出i
 for(int i=1;;++i){
       s+=i;
       if(s>n)break;
       cout<<i<<'\n';
    }

 

思路:二分:
对b[ ]排序,使用二分查找,看a[1~n]是否在b[ ]中出现,存在表示该数变切割线,切割线前存在数,表示存在一个片段,若a[n]不为切割线,则片段加一

 

1 sort(b+1,b+m+1);
2 for(int i=1;i<=n;++i){
3 if(!binary_search(a[i])&&binary_search(a[i+1]))ans++;
4 }
5 if(!binary_search(a[n]))ans++;

 

 
思路:dfs 分别求 s 和 t 到所有点的距离,同时记录方向,对于每个点,取距离较小的边,将方向与存的边比较
typedef long long ll;
const int N=6e5+5;
struct node{
    int u,v;
    ll w;
}e[N];
ll dis1[N],dis2[N],ed[N];
int ve[N],ne[N],h[N],idx=1,ans[N],ans1[N],ans2[N];//ans存编码

void add(int u,int v,ll w){
    ve[++idx]=v,ed[idx]=w,ne[idx]=h[u],h[u]=idx;
}

void dfs1(int x){
    for(int i=h[x];i;i=ne[i]){
        int t=ve[i];
        if(dis1[t])continue;
        dis1[t]=dis1[x]+ed[i];
        ans1[t]=(i^1)/2;//idx从2开始存,每一对相邻奇偶存的一条边,ans存储x->t边
        dfs1(t);
    }
}

void dfs2(int x){
    for(int i=h[x];i;i=ne[i]){
        int t=ve[i];
        if(dis2[t])continue;
        dis2[t]=dis2[x]+ed[i];
        ans2[t]=(i^1)/2;
        dfs2(t);
    }
}

int main(){
    int n,s,t;
    cin>>n>>s>>t;
    for(int i=1;i<n;++i){
        cin>>e[i].u>>e[i].v>>e[i].w;
        add(e[i].u,e[i].v,e[i].w);
        add(e[i].v,e[i].u,e[i].w);
    }
    dis1[s]=dis2[t]=1;
    dfs1(s),dfs2(t);
    ll res=0;
    for(int i=1;i<=n;++i){
        res+=min(dis1[i]-1,dis2[i]-1);
        if(i==s||i==t)continue;
        if(dis1[i]<dis2[i]){
            if(i==e[ans1[i]].u)ans[ans1[i]]=1;//从s和t开始dfs,实际路径相反
            else ans[ans1[i]]=2;
        }
        else{
            if(i==e[ans2[i]].u)ans[ans2[i]]=1;
            else ans[ans2[i]]=2;
        }
    }
    cout<<res<<'\n';
    for(int i=1;i<n;++i)cout<<ans[i];
    return 0;
}

 

 
思路:对于每个任务用时w,若在该天内完成能够满足时间要求,则完成该任务,否则该天剩余时间用来睡觉,再算出在能够完成该任务的情况下
所需全天睡觉的天数 l(最佳情况),即满足 xw+sum+lx(i+l)xp​/q (一天时间 − 将要完成的作业时间 + 当前总睡觉时间 + 天整天睡觉的总时长 ≥ 该天的 l 天后的要求总睡觉时长),若不满足则 l 天的范围 l  ≥ ( q(sum+xw)pix​ ) / ( x(pq) )  (向上取整)
 
void solve(){
    ll n,x,p,q,i=1,sum=0,t=0;//第i天,总睡觉时间sum,当天作业时间t
    cin>>n>>x>>p>>q;
    while(n--){
        ll w;
        cin>>w;
        if((x-t-w+sum)*q>=i*p*x&&x-t>w)t+=w;//做此任务能满足要求
        else{
            sum+=x-t;
            i++;
            ll l=ceil((q*(sum+x-w)-p*i*x)*1.0/(x*p-x*q));
            if(l>0){
                sum+=x*l;
                i+=l;
            }
            t=w;
        }
    }
    cout<<i;
}

 

 
思路:不及格人数<=( E * 总人数 )* 科目数量,不及格人数<=总人数 的情况下,可保证全部人可毕业,不及格人数尽可能大的情况下E越大,找出最大不及格人数, 满足不及格人数能整除科目数量,即可求出E
 1 int main(){
 2     int a,b;
 3     cin>>a>>b;
 4     for(int i=b;;--i){
 5         if(i%a!=0)continue;
 6         int c=i/a;
 7         double d=double(c)/b;
 8         cout << fixed << setprecision(16) <<d;
 9         break;
10     }
11     return 0;
12 }

 

 
思路:将原序列分为两段
 1  for (int i = n ; i > 0; --i) {
 2         if (i <= n) {
 3             for (int k = i; k <= n; ++k) {
 4                 cout << a[k] << ' ';
 5             }
 6         }
 7         for (int j = 1; j < i; ++j)
 8             cout << a[j] << ' ';
 9         cout<<'\n';
10         if(a[i-1]==n)break;
11     }

 

 
 思路:每一行满足1.第一个非空白字符为‘#’ 2.‘#’后至少一个空格 3.其后至少一个非空白字符
 1 for (int i = 0, j; i < n; i++)
 2 {
 3     getline(cin, s);
 4     j = 0;
 5     while (j < s.size()&&s[j]==' ')
 6         j++;
 7     if (j >= s.size()-1||s[j] != '#'||s[++j] !=' ')
 8         continue;
 9     while (j < s.size() && s[j] == ' ')
10         j++;
11     if (j >= s.size())
12         continue;
13     b++;
14 }

 

 
posted @ 2023-01-07 20:07  bible_w  阅读(54)  评论(0编辑  收藏  举报