题意:判断一个字符串是否由相同的两部分构成(左半和右半)。
思路:奇数个字符时不可以,偶数个直接判断前后两部分是否相同。
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+5;
typedef long long ll;
void solve()
{
string s;
cin>>s;
int ls = s.length();
if(ls%2==0 && s.substr(0,ls/2) == s.substr(ls/2)){
cout<<"YES\n";
} else {
cout<<"NO\n";
}
}
int main()
{
ios::sync_with_stdio(false);
int t=1;
cin>>t;
while(t--) solve();
return 0;
}
题意:给定一个整数n,判断完全平方数加完全立方数(有这个定义吗,不知道)的个数。注意:重复数字不做重复贡献,如:1只计算一次。
思路:跑一遍平方,跑一遍立方,可以用map或set来避免重复贡献。
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+5;
typedef long long ll;
void solve()
{
ll n,ans=0;
cin>>n;
map<ll,bool>mp;
for(int i=1;i*i<=n;i++){//平方
if(!mp[i*i]){
mp[i*i]=1;
ans++;
}
}
for(int i=1;i*i*i<=n;i++){//立方
if(!mp[i*i*i]){
mp[i*i*i]=1;
ans++;
}
}
cout<<ans<<endl;
}
int main()
{
ios::sync_with_stdio(false);
int t=1;
cin>>t;
while(t--) solve();
return 0;
}
题意:定义一种特殊加法。给定相加结果和一个加数,求另一个加数。
思路:反向模拟即可。建议用数字取余,比赛时用字符串模拟,人调试麻了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve(){
ll a,s;
cin >> a >> s;
string b;
while(s>0){
ll rem_a = a%10;
ll rem_s = s%10;
ll ans = (10+rem_s-rem_a)%10;
if(rem_a+ans==rem_s){
b = to_string(ans)+b;
a/=10; s/=10;
}else if(rem_a+ans==s%100){
b = to_string(ans)+b;
a/=10; s/=100;
}else {
cout << "-1\n"; return;
}
}
if(a!=0) {cout << "-1\n"; return;}//运算结束b不为零 -1
//去前导零
while(b.size()>1 && b.front()=='0'){
b = b.substr(1);
}
cout << b << '\n';
}
int main()
{
ios::sync_with_stdio(false);
int t=1;
cin>>t;
while(t--) solve();
return 0;
}
题意:m个商店,n个朋友。你只能去n-1个商店购物,各个商店带给你朋友的快乐值为一个m*n的矩阵。问:去完n-1个商店后所有朋友的快乐值最小的能有多大(最大化最小值)?
思路:由于可以去n-1个商店,所以其中n-1位朋友的快乐值可以通过去能最大化值的商店解决(试想如果可以去n个商店,那么每人找不同列最大值即可)。那么有两个人的礼物需要再同一商店购买,这就是二分check()函数的关键!另外注意:最大值不能超过每一列的最大值的最小值。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m;
bool check(ll mid,const vector<vector<ll> >& v)
{
for(int i=0;i<n;i++){
ll cnt = 0;
for(int j=0;j<m;j++){
if(v[i][j]>=mid) cnt++;
if(cnt>=2) return 1;//有两个人必须在同一商店
}
}
return 0;
}
void solve()
{
cin>>n>>m;
vector<vector<ll> > v(n,vector<ll>(m,0));
vector<ll>maxj(m,0);
ll high = 0,low = 1;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>v[i][j];
high=max(high,v[i][j]);
maxj[j]=max(maxj[j],v[i][j]);
}
}
ll minu = *min_element(maxj.begin(),maxj.end());//列最大值的最小值
while(low < high)
{
ll mid = (high + low + 1)/2;
//cout<<mid<<endl;
if(mid <= minu && check(mid,v)){
low = mid;
} else{
high = mid - 1;
}
}
cout<<low<<endl;
}
int main()
{
ios::sync_with_stdio(false);
int t=1;
cin>>t;
while(t--) solve();
return 0;
}