1607- Codeforces Round #753 (Div. 3)

A.Linear Keyboard

  • 题意:给定两个字符串a和b,字符串b为含26个不同小写字母的字符串。遍历字符串a中找到与字符串b中对应字符的下标,依次相减,取绝对值相加。
  • 解题思路:定义一个map<char,int>标记b中每个字母的下标,遍历a数字,通过下标直接相减。
  • 解题代码:
    #include<bits/stdc++.h>
    using namespace std;
    map<char,int>s;
    string a, b;
    int t;
    int solve(){
    	int ans=0;
    	cin>>b>>a;
    	for(int i=0;i<26;i++){
    		s[b[i]]=i+1;
    	}
    	for(int i=1;i<a.size();i++){
    		int x=abs(s[a[i]]-s[a[i-1]]);
    		ans+=x;
    	}
    	return ans;
    }
    int main(){
    	cin>>t;
    	while(t--){
    		cout<<solve()<<endl;
    	}
    	return 0;
    }

    

B. Odd Grasshopper   

  •  题意:给定x和n,代表蚱蜢起点和跳跃次数,每次跳跃的步数是自然数列(1 2 3......),跳跃方向:如果蚱蜢在跳跃之前所在的点坐标为偶数,则蚱蜢向左跳跃,否则他向右跳跃。求蚱蜢最终所处的位置。
  • 解题思路:观察样例范围为10的14次方,说明需要在模拟的基础上找规律,不然要超时。通尝试样例,发现每跳跃4次,都会回到起点。
  • 解题代码:
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll t, x, n;
    ll solve(ll x,ll n){
    	ll ans=x;
    	ll a=(n/4)*4;
    	for(ll i=a+1;i<=n;i++){
    		if(ans%2==0)ans-=i;
    		else ans+=i;
    	}
    	return ans;
    }
    int main(){
    	cin>>t;
    	while(t--){
    		cin>>x>>n;
    		cout<<solve(x,n)<<endl;
    	}
    	return 0;
    }
    

C. Minimum Extraction

  • 题意:给定一个数组,每次操作为删掉最小元素m,剩余元素减m。该操作不能应用于长度为1的数组。求最大的m。
  • 解题思路:极大化最小值(maximize a minimum),由于每一次变化都是全体变化,所以用相对的思想去理解题意就可以知道求的是最大的相邻差值。
  • 解题代码:
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=2e5+10;
    int t, n, ans;
    int s[N];
    
    int main(){
    	cin>>t;
    	while(t--){
    		ans=0;
    		scanf("%d",&n);
    		for(int i=1;i<=n;i++)scanf("%d",&s[i]);
    	
    		if(n==1){
    			cout<<s[1]<<endl;
    		}
    		else{
    			sort(s+1,s+1+n);
    			int cnt=0,num=0,ans=s[1];
    			for(int i=2;i<=n;i++){
    				num=s[i]-s[i-1];
    				ans=max(num,ans);
    			}
    			cout<<ans<<endl;
    		}
    	}
    	return 0;
    }
    
    
    
    

D. Blue-Red Permutation

  • 题意:给定一个长度为n的数组,每个元素有自己的颜色,蓝色只能进行减一操作,红色只能进行加一操作,问是否能够通过操作构成一个1--n的新数组。
  • 解题思路:让蓝色元素尽可能小,红色元素尽可能大,对红色元素和蓝色元素分别进行排序操作,遍历一遍外加判断条件即可。
  • 解题代码:
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=2e5+10;
    string s;
    int t, n, bb=1,rr=1,f1=1,f2=1;
    int b[N],r[N];
    int a[N];
    
    int main(){
    	cin>>t;
    	while(t--){
    		bb=1,rr=1,f1=1,f2=1;
    		cin>>n;
    		for(int i=0;i<n;i++)scanf("%d",&a[i]);
    		cin>>s;
    //		cout<<s<<"###"<<endl;
    		for(int i=0;i<n;i++){
    			if(s[i]=='B'){
    				b[bb]=a[i];
    				bb++;
    			}
    			else{
    				r[rr]=a[i];
    				rr++;
    			}
    		}
    //		cout<<bb<<' '<<rr<<endl;
    		if(bb!=1)sort(b+1,b+bb);
    		if(rr!=1)sort(r+1,r+rr);
    		for(int i=1;i<bb;i++){
    			if(b[i]<i){
    				f1=0;
    //				cout<<i<<" %% "<<b[i]<<endl;
    				break;
    			}
    		}
    //		for(int i=1;i<rr;i++)cout<<r[i]<<"@@"<<" ";
    //		cout<<endl;
    		for(int j=bb;j<=n;j++){
    			if(r[j-bb+1]>j){
    				f2=0;
    //				cout<<j<<" ## "<<r[j]<<endl;
    				break;
    			}
    		}
    		if(f1==0 || f2==0){
    			cout<<"NO"<<endl;
    		}
    		else{
    			cout<<"YES"<<endl;
    		}
    	}
    	return 0;
    }
    
    
    
    

 E. Robot on the Board 1

  • 题意:给出了机器人执行的指令序列。每个命令由符号“L”、“R”、“D”或“U”中的一个表示,并分别触发向左、向右、向下或向上的移动。机器人严格按照s中列出的顺序从第一个命令开始执行命令。如果机器人移动到板的边缘之外,它就会掉落并折断。导致机器人中断的命令被视为未成功执行。确定机器人应该从哪个单元开始移动,以便执行尽可能多的命令。
  • 解题思路:进行模拟,记录机器人移动时的上下限和左右限。当上下限的差值达到行值或左右限的差值达到列值,即结束模拟,此时执行的命令的下一个即为能够执的最后一条命令。根据最后的命令输出最后的答案。
  • 解题代码:
    #include<bits/stdc++.h>
    using namespace std;
    const int N=100200;
    typedef long long ll;
    
    string s;
    int t, n, m;
    void solve(string &s){
    	int h = 0, w = 0, up = 0, down = 0, left = 0, right = 0, cnt = 0;
    	int len = s.size();
    	for(int i = 0 ; i < len; i ++ ){
    		if(s[i] == 'U'){
    			h ++;
    			up = max(h, up);
    		}
    		else if(s[i] == 'D'){
    			h --;
    			down = min(h, down);
    		}
    		else if(s[i] == 'L'){
    			w --;
    			left = min(w, left);
    		}
    		else if(s[i] == 'R'){
    			w ++;
    			right = max(w, right);
    		}
    		if(up - down == n) break;
    		if(right - left == m) break;
    		cnt++;
    	}
    	
    	if(s[cnt] == 'U'){
    		cout << up << " " << -left + 1 << endl;
    	}else if(s[cnt] == 'L'){
    		cout << up + 1 << " " << -left << endl;
    	}else{
    		cout << up + 1 << " " << -left + 1 << endl;
    	}
    }
    
    int main(){
    	cin >> t;
    	while(t --){
    		cin >> n >> m;
    		cin >> s;
    		solve(s);
    	}
    	return 0;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值