1. 程式人生 > >普及組題解

普及組題解

–CSDN第一次創作

標題統計

簽到題,唯一需要注意的就是正向判斷
(作者唯一AC的一道題¥_¥)

    #include<cstdio>
    #include<cstring>
    int main()
    {
        char s[105];
        gets(s);
        int lens=strlen(s),ans=0;
        for(int i=0;i<lens;i++)
        if((s[i]>='A'&&s[i]<='Z')||(s[i]>='a'&&s[i]<='z')||(s[i]>='0'&&s[i]<='9'))
                    ans++;
        printf("%d\n",ans);
        return 0;
    }

龍虎鬥

這道題純列舉,特別是要注意開long long (其實不需要二分)!
作者只拿了80分…(附上簡潔的學生型程式碼)

#include<cstdio>
long long Abs(long long x)
{    
    if(x>=0)        
        return x; 
    return -x;
}
long long c[100005],l=0,h=0,Minn=0,n,m,p1,s1,s2,ans;
int main()
{
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
        scanf("%lld",&c[i]);
    scanf("%lld %lld %lld %lld",&m,&p1,&s1,&s2);
    c[p1]+=s1;
    for(int i=1;i<m;i++) 
        l+=c[i]*(m-i);
     for(int i=m+1;i<=n;i++)
        h+=c[i]*(i-m);
          Minn=Abs(l-h);
    for(int i=1;i<=n;i++)
    {
        if(i<m&&Abs(l+s2*(m-i)-h)<Minn)
        {
                Minn=Abs(l+s2*(m-i)-h);
                ans=i;        
        }
        if(i>m&&Abs(h+s2*(i-m)-l)<Minn)
        {
            Minn=Abs(h+s2*(i-m)-l);
                ans=i;
        }
    }    
    if(ans==0)        
        printf("%lld\n",m);    
    else       
        printf("%lld\n",ans);       
    return 0;
}

擺渡車

基本思想:
無論怎樣每個人的等待時間最多是2m(想一想,為什麼) ,
這樣就可以用dp[n][j]來表示(0<=j<2
m)到第i個人並且第i人等待j分鐘的最小等待時間。
詳細操作:
初始化dp[1][j]=j
當i-1個人的等k分鐘和i個人等j分鐘後能上同一輛車或i-1先發車i能做下一輛車
dp[i][j]=min(dp[i][j],dp[i-1][k]+j);
其實這道題很簡單
還不懂的話,上程式碼

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,t[505];
int dp[505][205],ans=0x3f3f3f3f;
int min(int x,int y)
{
    if(x<=y)
        return x;
    return y;
}
int main()
{
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&t[i]);
    sort(t+1,t+1+n);
    memset(dp,0x3f,sizeof(dp));
    for(int i=0;i<2*m;i++)
        dp[1][i]=i;
    for(int i=2;i<=n;i++)
        for(int j=0;j<2*m;j++)
            for(int k=0;k<2*m;k++)
                if(t[i-1]+k==t[i]+j||t[i-1]+k+m<=t[i]+j)
                    dp[i][j]=min(dp[i][j],dp[i-1][k]+j);
    for(int i=0;i<2*m;i++)
        ans=min(ans,dp[n][i]);
    printf("%d\n",ans);
}

對稱二叉樹

基本思想:搜尋,從低層向上遞迴
具體操作:
c[i]表示以i為根節點的完整二叉樹節點總數
v[i]表示以i為根節點的完整二叉樹點權總和
然後暴力判斷
相信你能看懂程式碼

#include<cstdio>
int n,ch[1000005][2],v[1000005],c[1000005],ans;
void read(int &x)
{
    x=0;
    int f=1;char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')f=0;c=getchar();}
    while(c<='9'&&c>='0'){x=(x<<3)+(x<<1)+c-'0';c=getchar();}
    x*=f;
}
bool pd(int a,int b)
{
    if(a==b)
        return 1;
    if(!a||!b)
        return 0;
    return v[a]==v[b]&&pd(ch[a][0],ch[b][1])&&pd(ch[a][1],ch[b][0]);
}
void DFS(int i)
{
    if(!i)
        return ;
    DFS(ch[i][0]);
    DFS(ch[i][1]);
    c[i]=c[ch[i][0]]+c[ch[i][1]]+1;
    v[i]+=v[ch[i][0]]+v[ch[i][1]];
    if(c[i]>ans&&pd(ch[i][0],ch[i][1]))
        ans=c[i];
    return ;
}
int main()
{
    read(n);
    for(int i=1;i<=n;i++)
        read(v[i]);
    for(int i=1;i<=n;i++)
    {
        read(ch[i][0]);
        read(ch[i][1]);
    }
    DFS(1);
    printf("%d\n",ans);
    return 0;
}