PROBLEM LINK:
Contest Division 1
Contest Division 2
Contest Division 3
Practice
Setter: Manan Bordia and Lavish Gupta
Tester: Abhinav Sharma
Editorialist: Taranpreet Singh
DIFFICULTY
Simple
PREREQUISITES
None
PROBLEM
Given two strings A and B of length N each. Find the number of indices i such that A[i\ldots N] \lt B[i \ldots N].
QUICK EXPLANATION
- If A_i \lt B_i, then index i is good. If A_i \gt B_i, then index is not good.
- If A_i = B_i, then index i is good if and only if index i+1 is good.
EXPLANATION
Letâs call an index i good if A[i\ldots N] \lt B[i \ldots N] holds.
Let us solve this problem for the easier cases first. Whenever we have A_i \neq B_i, we can immediately decide for index i whether it is good or not.
What happens when A_i = B_i? Weâd need to compare A_{i+1} and B_{i+1} and so on, to find the first position p where A_p \neq B_p. All indices from i to p are decided by whether A_p \lt B_p is true or not.
We can see that if A_i = B_i, then index i is good only if index i+1 is good. Letâs compute this from right to left. Maintain whether index i+1 is good or not. First check if A_i \neq B_i. If yes, check if index is good or not by comparing A_i and B_i.
Maintain a count of good indices.
nextGood = false # Whether index i+1 is good or not
count = 0
for i in N-1 to 0:
if A[i] == B[i]:
if nextGood: count++
else:
if A[i] < B[i]:
count++
nextGood = true
else:
nextGood = false
print count
TIME COMPLEXITY
The time complexity is O(N) per test case.
SOLUTIONS
Setter's Solution
#include <bits/stdc++.h>
using namespace std;
/*
------------------------Input Checker----------------------------------
*/
long long readInt(long long l,long long r,char endd){
long long x=0;
int cnt=0;
int fi=-1;
bool is_neg=false;
while(true){
char g=getchar();
if(g=='-'){
assert(fi==-1);
is_neg=true;
continue;
}
if('0'<=g && g<='9'){
x*=10;
x+=g-'0';
if(cnt==0){
fi=g-'0';
}
cnt++;
assert(fi!=0 || cnt==1);
assert(fi!=0 || is_neg==false);
assert(!(cnt>19 || ( cnt==19 && fi>1) ));
} else if(g==endd){
if(is_neg){
x= -x;
}
if(!(l <= x && x <= r))
{
cerr << l << ' ' << r << ' ' << x << '\n';
assert(1 == 0);
}
return x;
} else {
assert(false);
}
}
}
string readString(int l,int r,char endd){
string ret="";
int cnt=0;
while(true){
char g=getchar();
assert(g!=-1);
if(g==endd){
break;
}
cnt++;
assert('a'<=g and g<='z');
ret+=g;
}
assert(l<=cnt && cnt<=r);
return ret;
}
long long readIntSp(long long l,long long r){
return readInt(l,r,' ');
}
long long readIntLn(long long l,long long r){
return readInt(l,r,'\n');
}
string readStringLn(int l,int r){
return readString(l,r,'\n');
}
string readStringSp(int l,int r){
return readString(l,r,' ');
}
/*
------------------------Main code starts here----------------------------------
*/
const int MAX_T = 100000;
const int MAX_LEN = 1000000;
const int MAX_SUM_LEN = 1000000;
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
int sum_len = 0;
int max_n = 0;
int max_k = 0;
int yess = 0;
int nos = 0;
int total_ops = 0;
int n,k;
string s;
void solve()
{
n = readIntLn(1, MAX_LEN);
string a = readStringLn(1, MAX_LEN);
string b = readStringLn(1, MAX_LEN);
sum_len += n;
assert(a.length()==n && b.length()==n);
for(int i = 0 ; i < n ; i++)
{
int val_a = a[i] - 'a' ;
int val_b = b[i] - 'a' ;
assert(val_a >= 0 && val_a < 26) ;
assert(val_b >= 0 && val_b < 26) ;
}
int ans = 0;
if(a == b)
{
cout << ans << '\n' ;
return ;
}
for(int i = 0 ; i < n ; i++)
{
int flag = 0 ;
for(int j = i ; j < n ; j++)
{
if(a[j] < b[j])
{
ans += (j-i+1) ;
i = j ;
break ;
}
if(a[j] > b[j])
{
i = j ;
break ;
}
if(j == n-1)
flag = 1 ;
}
if(flag)
break ;
}
cout<<ans<<'\n';
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r" , stdin);
freopen("output.txt", "w" , stdout);
#endif
// fast;
int t = 1;
t = readIntLn(1,MAX_T);
for(int i=1;i<=t;i++)
{
solve();
}
assert(sum_len <= MAX_SUM_LEN);
assert(getchar() == -1);
cerr<<"SUCCESS\n";
cerr<<"Tests : " << t << '\n';
// cerr<<"maxN : " << max_n << '\n';
// cerr<<"maxK : " << max_k << '\n';
cerr<<"Sum of lengths : " << sum_len << '\n';
// cerr<<"Maximum length : " << max_n << '\n';
// cerr<<"Total operations : " << total_ops << '\n';
// cerr<<"Answered yes : " << yess << '\n';
// cerr<<"Answered no : " << nos << '\n';
}
Tester's Solution
#include <bits/stdc++.h>
using namespace std;
/*
------------------------Input Checker----------------------------------
*/
long long readInt(long long l,long long r,char endd){
long long x=0;
int cnt=0;
int fi=-1;
bool is_neg=false;
while(true){
char g=getchar();
if(g=='-'){
assert(fi==-1);
is_neg=true;
continue;
}
if('0'<=g && g<='9'){
x*=10;
x+=g-'0';
if(cnt==0){
fi=g-'0';
}
cnt++;
assert(fi!=0 || cnt==1);
assert(fi!=0 || is_neg==false);
assert(!(cnt>19 || ( cnt==19 && fi>1) ));
} else if(g==endd){
if(is_neg){
x= -x;
}
if(!(l <= x && x <= r))
{
cerr << l << ' ' << r << ' ' << x << '\n';
assert(1 == 0);
}
return x;
} else {
assert(false);
}
}
}
string readString(int l,int r,char endd){
string ret="";
int cnt=0;
while(true){
char g=getchar();
assert(g!=-1);
if(g==endd){
break;
}
cnt++;
assert('a'<=g and g<='z');
ret+=g;
}
assert(l<=cnt && cnt<=r);
return ret;
}
long long readIntSp(long long l,long long r){
return readInt(l,r,' ');
}
long long readIntLn(long long l,long long r){
return readInt(l,r,'\n');
}
string readStringLn(int l,int r){
return readString(l,r,'\n');
}
string readStringSp(int l,int r){
return readString(l,r,' ');
}
/*
------------------------Main code starts here----------------------------------
*/
const int MAX_T = 100000;
const int MAX_LEN = 1e6;
const int MAX_SUM_LEN = 1e6;
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
int sum_len = 0;
int max_n = 0;
int max_k = 0;
int yess = 0;
int nos = 0;
int total_ops = 0;
int n,k;
string s;
void solve()
{
n = readIntLn(1, 1e6);
string a = readStringLn(1, MAX_LEN);
string b = readStringLn(1, MAX_LEN);
sum_len += n;
assert(a.length()==n && b.length()==n);
int ans = 0;
int f=0;
for(int i=n-1; i>=0; i--){
if(a[i]<b[i]){
if(!f) f=1;
}
else if(a[i]>b[i]){
if(f) f=0;
}
ans+=f;
}
cout<<ans<<'\n';
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r" , stdin);
freopen("output.txt", "w" , stdout);
#endif
fast;
int t = 1;
t = readIntLn(1,MAX_T);
for(int i=1;i<=t;i++)
{
solve();
}
assert(sum_len <= MAX_SUM_LEN);
assert(getchar() == -1);
cerr<<"SUCCESS\n";
cerr<<"Tests : " << t << '\n';
// cerr<<"maxN : " << max_n << '\n';
// cerr<<"maxK : " << max_k << '\n';
cerr<<"Sum of lengths : " << sum_len << '\n';
// cerr<<"Maximum length : " << max_n << '\n';
// cerr<<"Total operations : " << total_ops << '\n';
// cerr<<"Answered yes : " << yess << '\n';
// cerr<<"Answered no : " << nos << '\n';
}
Editorialist's Solution
import java.util.*;
import java.io.*;
class STRCOMPARE{
//SOLUTION BEGIN
void pre() throws Exception{}
void solve(int TC) throws Exception{
int N = ni();
String A = n(), B = n();
int ans = 0;
boolean small = false;
for(int i = N-1; i>= 0; i--){
if(A.charAt(i) < B.charAt(i)){
ans++;
small = true;
}else if(A.charAt(i) == B.charAt(i)){
if(small)
ans++;
}else small = false;
}
pn(ans);
}
//SOLUTION END
void hold(boolean b)throws Exception{if(!b)throw new Exception("Hold right there, Sparky!");}
static boolean multipleTC = true;
FastReader in;PrintWriter out;
void run() throws Exception{
in = new FastReader();
out = new PrintWriter(System.out);
//Solution Credits: Taranpreet Singh
int T = (multipleTC)?ni():1;
pre();for(int t = 1; t<= T; t++)solve(t);
out.flush();
out.close();
}
public static void main(String[] args) throws Exception{
new STRCOMPARE().run();
}
int bit(long n){return (n==0)?0:(1+bit(n&(n-1)));}
void p(Object o){out.print(o);}
void pn(Object o){out.println(o);}
void pni(Object o){out.println(o);out.flush();}
String n()throws Exception{return in.next();}
String nln()throws Exception{return in.nextLine();}
int ni()throws Exception{return Integer.parseInt(in.next());}
long nl()throws Exception{return Long.parseLong(in.next());}
double nd()throws Exception{return Double.parseDouble(in.next());}
class FastReader{
BufferedReader br;
StringTokenizer st;
public FastReader(){
br = new BufferedReader(new InputStreamReader(System.in));
}
public FastReader(String s) throws Exception{
br = new BufferedReader(new FileReader(s));
}
String next() throws Exception{
while (st == null || !st.hasMoreElements()){
try{
st = new StringTokenizer(br.readLine());
}catch (IOException e){
throw new Exception(e.toString());
}
}
return st.nextToken();
}
String nextLine() throws Exception{
String str = "";
try{
str = br.readLine();
}catch (IOException e){
throw new Exception(e.toString());
}
return str;
}
}
}
Feel free to share your approach. Suggestions are welcomed as always.