ICPC-思维-CF#342div2 A(!)+B+C

http://codeforces.com/contest/625
A
这个题,好恶心。
题解说:(剩钱-c)/(b-c)才是可以进行第二种交换的次数

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
const ll mod=998244353;
const int maxn=2e5;
int main(){
	int t;
	ll n,a,b,c;
	cin>>n;
	cin>>a>>b>>c;
    ll one=a,two=b-c;
    ll sum1=n/one,yu1=n%one,ci;
    while(yu1/b>0){
        ci=(yu1-c)/two;
        yu1=yu1-ci*two;
        sum1+=ci;
    }
    ll yu2=n,sum2=0,ans=0;
    while(yu2/b>0){
        ci=(yu2-c)/two;
        yu2=yu2-ci*two;
        sum2+=ci;
    }
    sum2+=yu2/one;
    yu2=yu2%one;

    ans=max(ans,sum2);
    ans=max(sum1,ans);
    cout<<ans<<endl;
	return 0;
}

下面是我一开始想的,比较丑
首先,这个两种方案同时比较,可以避免做一些错误的贪心判断
再者,在判断剩下的钱中是否要进行购入的时候,判断标准是钱数而不是个数
注意:我认为(剩钱-b)/(b-c)是第二种交换的次数
但是我对于仅大于b却不能进行第二种交换的剩钱进行特判
这种钱的判断标准是选a或者选b的最小钱数

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
const ll mod=998244353;
const int maxn=2e5;
int main(){
	int t;
	ll n,a,b,c;
	cin>>n;
	cin>>a>>b>>c;
    ll one=a,two=b-c;
    ll sum1=n/one,yu1=n%one,ci;
    while(yu1/b>0){
        ci=(yu1-b)/two;
        if(ci==0&&yu1>=b){//b-2b
            if(yu1/a>0&&yu1/a*a<yu1/b*two){
                yu1=yu1-yu1/a*a;
                sum1=sum1+yu1/a;
            }
            else {
                yu1-=two;
                sum1++;
            }
        }
        else{
            yu1=yu1-ci*two;
            sum1+=ci;
        }
    }
    
    ll yu2=n,sum2=0,ans=0;
    while(yu2/b>0){
        ci=(yu2-b)/two;
        if(ci==0&&yu2>=b){
            if(yu2/a>0&&yu2/a*a<yu2/b*two){
                yu2=yu2-yu2/a*a;
                sum2+=yu2/a;
            }
            else {
                yu2-=two;
                sum2++;
            }
        }
        else{
            yu2=yu2-ci*two;
            sum2+=ci;
        }
    }
    sum2+=yu2/one;
    yu2=yu2%one;
    
    ans=max(ans,sum2);
    ans=max(sum1,ans);
    cout<<ans<<endl;
	return 0;
}

B
这个题,就是找不可重叠的子串数量,暴力即可,找到一个子串就将最后一个字符改成#

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
const ll mod=998244353;
const int maxn=2e5;
string s,a;
bool check(int i){
    for(int j=1;j<a.size();j++){
        if(s[i+j]!=a[j])return false;
    }
    return true;
}
int main(){
	cin>>s;
	cin>>a;
	int sum=0;
	for(int i=0;i<s.size();i++){
        if(a[0]==s[i]){
            if(check(i)){
                sum++;
                s[i+a.size()-1]='#';
            }
        }
	}
    cout<<sum<<endl;
	return 0;
}

C
分成,[1,k-1] 和 [k,n]
前半段,1 2 …(k-1)*n 这样一行一行去填充
后半段,(k-1)*n+1 (k-1)*n+2 这样一行一行再填充
就OK了

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
const ll mod=998244353;
const int maxn=500;
int num[maxn+5][maxn+5];
int main(){
    int n,k;
	cin>>n>>k;
	int cnt=1;
	for(int j=1;j<=n;j++){
        for(int i=1;i<k;i++){
            num[j][i]=cnt;
            cnt++;
        }
	}
	//cout<<cnt<<endl;
	for(int j=1;j<=n;j++){
        for(int i=k;i<=n;i++){
           num[j][i]=cnt;
           cnt++;
        }
	}
	ll ans=0;
	for(int i=1;i<=n;i++)ans+=num[i][k];
	cout<<ans<<endl;
	for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cout<<num[i][j]<<" ";
        }
        cout<<endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值