找四个数a,b,c,d,中的最大数


int main()
 {
     int a,b,c,d,max;
     scanf("%f,%f,%f,%f",&a,&b,&c,&d);
     max=(a>b)?a:b;
     max=(max>c)?max:c;
     max=(max>d)?max:d;
     printf("%f\n",max);
    return 0;
}

将%f换成%d能成功运行,为什么%f不行

参考GPT和自己的思路:在这段代码中,输入的是四个整数,但是使用了错误的格式控制字符串"%f"来接收输入。"%f"是用来接收浮点数的格式控制字符串,而输入的是整数,所以应该使用"%d"来接收。由于使用了错误的格式控制字符串,导致输入的整数无法正确转换为浮点数,最终导致程序运行时出现错误。

因为a,b,c,d,max本身定义是int型,如果你要更改为%f,需要把int a,b,c,d,max;修改float a,b,c,d,max;
希望能解决你的问题。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/171732
  • 这篇博客也不错, 你可以看下利用最小堆编程实现给定权值集合下构造相应霍夫曼树的算法,并解决以下问题: 有一电文共使用五种字符a,b,c,d,e,其出现频率依次为4,7,5,2,9。
  • 除此之外, 这篇博客: 2019年湘潭大学程序设计竞赛(重现赛)部分题解(A、B、C、D、E、F)中的 输出 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    复制
    1

    C题打表找规律,还不会打表的看我代码的注释部分。

    至于官方解法,不知道怎么证的。

    可以看看

    然后还有一个知识点。如果是求(L,R);我们可以求这个(0,R)-(0,L-1)代替(L,R)。好好想想~

    还有人找到规律不知道怎么写的吗?

    1,193,385,577.等差数都为192.

    1,192*1+1,192*2+1,192*3+1......以此类推(等差数列通项)。

    先不考虑1,都减一个1.(待会加回来就可以了 加个(L-R+1))

    0,192*1,192*2,192*3;

    那么只需要统计区间内192的个数*192(前面已经说了(0,R)-(0,L-1)代替(L,R))

    这里还有一个知识点。若R/192=num,那么num就是0到R区间内包含192的个数(可以自己去证明几个数玩玩)

     

    那么求出num了,答案就是num*(num+1)/2*192+(L-R+1).(num*(num+1)/2是等差数列求和,上了大学,高中知识快忘了吧,快去百度等差数列怎么求和的)

    数列就变成了

     

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int N=1e3+10;
    const ll inf=1e9;
    ll sum[N*40];
    int ls[N*40],rs[N*40];
    int cnt=0,rt;
    /*void init()
    {
    	for(ll i=1;i<=1e3;i++)
    	{
    		if((i*i*i)%192==1)
    		{
    			printf("i:%lld\n",i);
    		}
    	}
    }*/
    int main()
    {
    	int t;
    	//init();
    	cin>>t;
    	while(t--)
    	{
    		ll l,r;
    		scanf("%lld%lld",&l,&r);
    		ll n1=0,n2=0;
    		if(l>=2) n1=(l-2)/192;
    		if(r>=1)	n2=(r-1)/192;
    		//printf("n1:%lld\n",n1);
    		//printf("n2:%lld\n",n2);
    		ll a1=n1*(n1+1)*192/2;
    		ll a2=n2*(n2+1)*192/2;
    		//printf("a2:%lld a1:%lld\n",a2,a1);
    		ll ans=a2-a1+n2-n1;
    		if(l==1) ans++;
    		printf("%lld\n",ans);
    	}
    }

    下面是许老师的代码,多简洁

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    ll gao(ll n)
    {
        int m=n/192;
        if(n%192)
            m++;
        return 1ll*(1+192*(m-1)+1)*m/2;
    }
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
            int l,r;
            cin>>l>>r;
            ll ans=gao(r);
            ans-=gao(l-1);
            cout<<ans<<endl;
        }
    }

    链接:https://ac.nowcoder.com/acm/contest/893/D
    来源:牛客网
     

    有n堆石子排成一排,第i堆石子有aiai个石子。
    每次,你可以选择任意相邻的两堆石子进行合并,合并后的石子数量为两堆石子的和,消耗的体力等价于两堆石子中石子数少的那个。
    请问,将所有的石子合并成一堆,你所消耗的体力最小是多少?

    第一行是一个整数T(1≤T≤20)T(1≤T≤20),表示样例的个数。
    每个样例的第一行是一个整数n(1≤n≤10000)n(1≤n≤10000),表示石子堆的数量。
    第二行是n个整数ai(1≤ai≤109)ai(1≤ai≤109)
    
    每行输出一个样例的结果。

    示例1

    复制

    2
    2
    1 2
    1
    1
    

    复制

    1
    0
    
    巨大的输入,请使用C风格的输入。

    感觉题解讲的很清楚了。管你是不是选择相邻的。我永远从最大的那一堆跟它附近的堆合并。最大堆合并一个堆后还是最大的堆。那么代价就不会加上最大堆的值。

    所以我的做法是排个序,从1加n-1就可以了。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e4+10;
    ll a[N];
    int main()
    {
    	int t;
    	cin>>t;
    	while(t--)
    	{
    		int n;
    		scanf("%d",&n);
    		for(int i=1;i<=n;i++)
    		{
    			ll x;
    			scanf("%lld",&a[i]);
    		}
    		ll ans=0;
    		sort(a+1,a+1+n);
    		for(int i=1;i<=n-1;i++) ans+=a[i];
    		printf("%lld\n",ans);
    	}
    }

    链接:https://ac.nowcoder.com/acm/contest/893/F
    来源:牛客网
     

    你有一个长度为 n 的 01 串S,你可以执行最多 m 次操作。
    对于每次操作,你可以选择一个位置 i 满足 1≤i≤n1≤i≤n,翻转这一位的值,0变成1,1变成0。
    定义一个 01 串的价值为其中最长连续0的个数和最长连续1的个数的较大值,求S在经过最多m次操作后的最大价值。

    * 第一行一个整数 T ,表示接下来有 T 个样例。
    * 首先输入n,m,表示S串的长度n和操作次数m,其中1≤n≤1000001≤n≤100000,0≤m≤10000≤m≤1000;
    * 接下来输入一个长度为n的字符串S。
    
    一个整数,表示题面上描述的最大价值。

    示例1

    复制

    2
    5 1
    00101
    2 1
    01

    复制

    4
    2
    第一个串翻转第三个位置,00001的价值为4;第二个串翻转第一个位置,11的价值为2。

    F题我的做法不太正确哈,我是纯暴力。从每一个点出发,要么向左延伸,要么向右延伸,求最大值。时间复杂度:O(1e8);

    正确做法请看官方题解:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e6+10;
    char s[N];
    int t,a[N],n,m;
    struct node
    {
    	int x,y;
    }b[N];
    int call(int id,int m)
    {
    	int pre=a[id];
    	int num=1;
    	int l=id-1,r=id+1;
    	while(m&&l>=1)
    	{
    		if(a[l]!=pre)m--;
    		num++;
    		l--;
    	}
    	while(l>=1&&a[l]==pre)l--,num++;
    	while(r<=n&&a[r]==pre) r++,num++;
    	return num;
    }
    int calr(int id,int m)
    {
    	int pre=a[id];
    	int num=1;
    	int l=id-1,r=id+1;
    	while(m&&r<=n)
    	{
    		if(a[r]!=pre)m--;
    		num++;
    		r++;
    	}
    	while(l>=1&&a[l]==pre)l--,num++;
    	while(r<=n&&a[r]==pre) r++,num++;
    	return num;
    }
    int main()
    {
    	int t;
    	cin>>t;
    	while(t--)
    	{
    		scanf("%d%d",&n,&m);
    		scanf("%s",s+1);
    		for(int i=1;i<=n;i++) a[i]=s[i]-'0';
    		int ans=0;
    		for(int i=1;i<=n;i++)
    		{
    			int pre=a[i];
    			int num=0;
    			int a1=call(i,m);
    			int a2=calr(i,m);
    			num=max(a1,a2);
    			ans=max(ans,num);
    		}
    		printf("%d\n",ans);
    	}
    }
    /*
    100
    
    14 6
    11110000001111
    100
    12 1
    100001110111
    15 1
    000100001110111
    */

    再贴一下正确做法的代码,来自hsx

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int pref[105000];
     
    int main(){
        int t;
        cin>>t;
        while(t--){
            int n,m;
            cin>>n>>m;
            string s;
            cin>>s;
             
            for(int i=0;i<n;i++){
                if(s[i]=='1')   pref[i+1]=pref[i]+1;//统计1的个数 
                else pref[i+1]=pref[i];
            }
             
            int ans=0;
            for(int i=1;i<=n;i++){//这样也阔以咯 
                int l=i;
                int r=n;
                while(l<=r){
                    int mid=(l+r)/2;
                    if(pref[mid]-pref[i-1] <= m){
                        ans=max(ans,mid-i+1);
                        l=mid+1;
                    }
                    else r=mid-1;
                }
            }
             
            for(int i=1;i<=n;i++){
                int l=i;
                int r=n;
                while(l<=r){
                    int mid=(l+r)/2;
                    if((mid-i+1) - (pref[mid]-pref[i-1]) <= m){//0的个数 
                        ans=max(ans,mid-i+1);
                        l=mid+1;
                    }
                    else r=mid-1;
                }
            }
            printf("%d\n",ans);
        }
         
        return 0;
    }

    补个E题

    链接:https://ac.nowcoder.com/acm/contest/893/E
    来源:牛客网
     

    在ACM队暑假集训的某一天,实验室里有 n n个人。因为天气很热,大家都很想吃西瓜。
    于是Eric买了 m m个西瓜拿到了实验室。
    Eric把这 n n个人分别编号为 1,2,3...n 1,2,3...n,他希望这 n n个人循环轮流来吃西瓜。
    也就是说从 1 1号开始,然后 2 2号, 3 3号...  n n号依次吃西瓜, n n号吃完后又轮到 1 1号来吃,直到这 m m个西瓜被吃完。
    而这 n n个人每个人有一个肚量值,第i个人的肚量值为 ai ai。
    lililalala是这 n n个人肚量值最大的人,不仅如此,他还非常贪吃,每次轮到他吃西瓜时,都会直接吃掉等同于他的度量值数量的西瓜。如果剩余的西瓜已经不够吃了,那么他会把所有西瓜直接吃完。(是的他很能吃)
    除了lililalala以外的其他人,对于第 i i号每次吃西瓜可以选择吃掉 [1,ai] [1,ai]中任意整数数量个西瓜。当然,不能超过当前剩余的西瓜数量。
    为了使吃西瓜更有意思一些,Eric规定如果在轮到某个人吃西瓜时没有西瓜了,那么由他来打扫一次实验室。(是的大家都很能吃)
    其他人都觉得lililalala吃的太多了应该由他来打扫卫生。请问在其他人串通好的情况下能否合理安排每个人的行动使得吃完西瓜后由lililalala来打扫卫生?

    第一行一个数字T(1≤T≤50)T(1≤T≤50)--样例个数。 
    每个样例包含两行。 
    第一行两个数字n,m(1≤n≤105,0≤m≤106)n,m(1≤n≤105,0≤m≤106)。
    第二行 n n个数字a1,a2...an(1≤ai≤107)a1,a2...an(1≤ai≤107),以空格分隔。 
    保证所有样例中肚量最大的人只有一个。这个人是lililalala。 
    保证所有样例中 ∑n ∑n不超过 3×106 3×106。 
    保证所有样例中 ∑m ∑m不超过 107 107。
    
    每个样例输出一行,输出”YES”如果合理安排可以使得最后由lililalala来打扫卫生,否则输出“NO”。

    示例1

    复制

    2  
    4 3  
    1 2 3 2  
    5 8  
    1 2 3 2 1

    复制

    YES
    NO

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^