A. Three Strings(思維)
-
題意: 給三個相同長度 n 字符串 a,b,c,c 每個字符必須和 a 或者 b 的相應下標字符交換,問經過 n 次變換後 a 是否可以和 b 相同。
-
思路: a 的字符與 c 的相同或者 b 的字符與 c 的相同既符合交換。如果三個字符都相同也是一樣的,交換後還是 a 和 b 還是相同。
Code:
#include <iostream>
using namespace std;
typedef long long ll;
int main(){
int t; cin>>t;
while(t--){
string a,b,c; cin>>a>>b>>c;
ll len=a.length();
int flag=1;
for(int i=0;i<len;i++){
if(a[i]==c[i] || b[i]==c[i])
continue;
else{
flag=0;
break;
}
}
if(flag) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
B. Motarack’s Birthday(思維)
- 題意: 給一個長度爲 n 的數組,-1 代表沒有數,你需把空位補上相同的 k ,使得數組相鄰元素中的最大的差值的絕對值最小。
- 思路: 先找出旁邊有空位的數的最大值和最小值,然後取中間值作爲 k,將空位全部補上,遍歷一遍數組,輸出最大的差值的絕對值。
Code:
#include <iostream>
#include <cstring>
#include <cmath>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N=1e5+10;
int a[N];
int main(){
int t; cin>>t;
while(t--){
memset(a,0,sizeof(a));
int n; cin>>n;
int maxn=0,minn=inf,flag=0;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]!=-1) flag=1;
}
for(int i=1;i<=n;i++){
if(a[i]!=-1 && (a[i-1]==-1 || a[i+1]==-1)){
maxn=max(maxn,a[i]);
minn=min(minn,a[i]);
}
}
if(!flag){
cout<<0<<' '<<0<<endl;
continue;
}
int mid=(maxn+minn)/2;
for(int i=1;i<=n;i++){
if(a[i]==-1)
a[i]=mid;
}
int ans=0;
for(int i=2;i<=n;i++)
ans=max(ans,(int)abs(a[i]-a[i-1]));
cout<<ans<<' '<<mid<<endl;
}
return 0;
}
C. Ayoub’s function(思維)
-
題意: 給長度 n ,m 個 1,構造出一個含 1 子串數量最大的字符串,求最多的含 1 子串數量。
-
思路:
- 用子串總數量減掉不含 1 子串數量即爲含 1 子串數量。一個字符串子串數量爲 n*(1+n) / 2。
- m 個 1 把 n-m 個 0 分割成 m+1 部分,要使得含 1 子串數量最多,就得將 0 平均分給這 m+1 部分。a = (n-m) / (m+1)就是平均每份 0 的數量,剩下的 b = (n-m)%(m+1) 就在 m+1 份放個 1 。沒放 1 的部分就有 m+1-b 份。
- 放 1 部分不含 0 的子串數量有 b*(a+2)*(a+1)/2 ,不放 1 部分不含 0 的子串數量有 c(1+a)a/2。
Code:
#include <iostream>
using namespace std;
typedef long long ll;
int main(){
int t; cin>>t;
while(t--){
ll n,m; cin>>n>>m;
ll a = (n-m)/(m+1);
ll b = (n-m)%(m+1);
ll c = m+1-b;
cout<<(1+n)*n/2-b*(a+2)*(a+1)/2-c*(1+a)*a/2<<endl;
}
return 0;
}
D. Time to Run(構造)
-
題意: 給一個 n*m 的圖,路線在圖中已標出,問能否在圖中走 k 步,路線不能重複,點可以重複。如果不能走,輸出“NO”,否則輸出 “YES” ,總步驟,每個步驟不能超出 4 個步數,並且總步驟數不能超過 3000 次。
-
思路: 走法如圖所示
- 當沒走到第 m 列時,每一列都要進行 n-1 次 “D”,n-1 次 “RLU”,1 次 “R”。
- 當走到第 m 列時,要進行 n-1 次 “D”,n-1 次 “U”,m-1 次 “L”。
Code:
#include <iostream>
#include <vector>
using namespace std;
struct node{
int cnt;
string str;
node(int sum,string s){
cnt=sum;
str=s;
}
};
vector<node> a;
void push(node x){
if(x.cnt!=0)
a.push_back(x);
}
int main(){
int n,m,k; cin>>n>>m>>k;
if(4*n*m-2*n-2*m<k)
cout<<"NO"<<endl;
else{
cout<<"YES"<<endl;
int cow=1;
while(k){
if(cow!=m){
if(k>=(n-1)){
push({n-1,"D"});
k-=(n-1);
}
else{
push({k,"D"});
k=0;
}
if(k==0) break;
if(k>=3*(n-1)){
push({n-1,"RLU"});
k-=3*(n-1);
}
else{
push({k/3,"RLU"});
if(k%3==1) push({1,"R"});
else if(k%3==2) push({1,"RL"});
k=0;
}
if(k==0) break;
if(k>=1){
push({1,"R"});
k--;
}
}
else{
if(k>=n-1){
push({n-1,"D"});
k-=(n-1);
}
else{
push({k,"D"});
k=0;
}
if(!k) break;
if(k>=n-1){
push({n-1,"U"});
k-=(n-1);
}
else{
push({k,"U"});
k=0;
}
if(!k) break;
if(k>=m-1){
push({m-1,"L"});
k-=(m-1);
}
else{
push({k,"L"});
k=0;
}
}
cow++;
}
cout<<a.size()<<endl;
for(int i=0;i<a.size();i++)
cout<<a[i].cnt<<' '<<a[i].str<<endl;
}
return 0;
}