题目大意:输入一个字符串,该字符串包含6个数字,如果前三位数字等于后三位数字之和,输出”YES“,否则输出”NO“;
思路: 签到题,直接把前三位和后三位的和加起来,比较是否相同即可。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
for(int i = 1;i<=t;i++)
{
string a;
cin>>a;
int sum1 = 0,sum2 = 0;
for(int j = 0;j <= 2;j ++) sum1 += a[j]-'a';
for(int j = 3;j <= 5;j ++) sum2 += a[j]-'a';
if(sum1 == sum2) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
题目大意:一共有n个箱子,在每个箱子里有ai个糖果,现在需要把箱子分给朋友,但要求,每个朋友获得的糖果数相同,每个箱子给不同的朋友,问,他需要吃掉多少个糖果,才能分配均匀。
思路:可以转化为把不同箱子中包含糖果最少的那个数分给朋友们,既求糖果数总和和箱子数*最小糖果数的差值.
#include<bits/stdc++.h>
using namespace std;
const int N = 60;
int a[N];
int main()
{
int t;
cin>>t;
for(int k = 1;k <= t;k++)
{
int sum = 0;
int mi = 0x3f3f3f3f;
int res = 0;
int n;
cin>>n;
for(int i = 1;i <= n;i ++)
{
int x;
cin>>x;
sum += x;
if(mi > x) mi = x;
}
res = sum - mi * n;
cout<<res<<endl;
}
return 0;
}
题目大意: 输入n个长度为m的单词, 在这n个单词中,两两间每一位上的字母距离的和的最小值。
思路:字母间的距离即为字母间ASCII码的差值,注意数据范围,n在50以内,m在8以内,直接暴力枚举字母间距离之和然后求最小值即可。
#include<bits/stdc++.h>
using namespace std;
const int N = 60;
string str[60];
int main()
{
int t;
cin>>t;
for(int k = 1;k <= t;k++)
{
int idx;
int sum = 0x3f3f3f3f;
int n,m;
cin>>n>>m;
for(int i = 1;i <= n;i ++) cin>>str[i];
for(int i = 1;i < n;i++)
{
for (int j = i + 1; j <= n; j++)
{
idx = 0;
for(int p = 0;p < m;p ++)
{
int a = str[i][p] - 'a';
// cout<<a<<endl;
int b = str[j][p] - 'a';
//cout<<b<<endl;
idx += abs(a - b);
// cout<<idx<<endl;
}
sum = min(sum,idx);
}
// sum = min(sum,idx);
}
cout<<sum<<endl;
}
return 0;
}
题目大意:给一个n行m列的棋盘,每个格子上都有一个非负整数,把一个主教放在棋盘的一个位置,求被主教攻击的 所有格子上的数字的和的最大值(主教能攻击正负对角线上的所有棋子)
思路:数据范围比较小,直接枚举即可。枚举每一个位置,在该位置枚举四个方向所有能够到达的格子上的数之和。最后求最大值即可。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t, n, m;
cin >> t;
while(t--)
{
cin >> n >> m;
int ara[n+8][m+8];
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
cin >> ara[i][j];
}
}
int sum, mx = -0x3f3f3f3f;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
sum = 0;
for(int a = i, b = j; a < n && b < m; a++, b++)
{
sum += ara[a][b];
}
for(int a = i-1, b = j-1; a >= 0 && b >= 0; a--, b--)
{
sum += ara[a][b];
}
for(int a = i+1, b = j-1; a < n && b >= 0; a++, b--)
{
sum += ara[a][b];
}
for(int a = i-1, b = j+1; a >= 0 && b < m; a--, b++)
{
sum += ara[a][b];
}
if(mx < sum)
{
mx = sum;
}
}
}
cout << mx << endl;
}
return 0;
}
题目大意: 有n个糖果,每个糖果的含糖量是ai,一共有q次询问,每次询问给一个x,问最少吃多少个糖,总的含糖量能大于等于x。
思路:维护一个前缀和来存糖果的总的含糖量,然后在每次询问中,通过二分查找找到第一个大于等于x的下标,然后,如果下标大于等于n,则说明全部加起来也不够x,输出-1,否则输出pos(也就是二分查找到的下标)的上一位,既pos - 1; (注意数据范围,如果裸暴力找第一个大于等于x的的下标的话,会TLE的。实测:在第6个样例就爆了)
(暴力大法,反面教材,这里就不上代码了)
(二分查找)
#include<bits/stdc++.h>
using namespace std;
const int N = 1.5e5+10;
int a[N],sum[N];
int ans;
bool cmp(int b,int c)
{
return b > c;
}
int main()
{
int t;
cin>>t;
for(int te = 1;te <= t;te ++)
{
memset(a,0,sizeof a);
memset(sum,0,sizeof sum);
int n,q;
cin>>n>>q;
for(int i = 1;i <= n;i ++) cin>>a[i];
sort(a+1,a+1+n, cmp);
sum[0] = 0;
for(int i = 1;i <= n;i ++) sum[i] = sum[i-1] + a[i]; //前缀和
for(int qe = 1;qe <= q;qe ++)
{
int x;
cin>>x;
int pos = lower_bound(sum + 1,sum + n + 1,x) - sum - 1;
if(pos >= n) cout<<"-1"<<endl;
else cout<<pos+1<<endl;
}
}
return 0;
}
题目大意: 首先,给一个长度为n的数组,和出现次数k,需要找到 一对l,r,保证对于每一个x,l<=x<=r,x在数组中出现次数大于等于k,并且要求r-l的值最小。
思路:用map存每个数出现的次数,然后去重存入vector中,对vector数组进行排序,然后双指针直接枚举就好。
注意:在用map存数字出现次数的时候,记录一下数字出现的最大次数,如果小于k,则无解,输出-1即可。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int main() {
int t;
cin >> t;
while (t--) {
int n, k, x;
cin >> n >> k;
map<int, int> m, v;
vector<int> q;
int mx = 0;
for (int i = 1; i <= n; i++) {
scanf("%d", &x);
m[x]++;
if (m[x] >= k && !v[x]) {
v[x] = 1;
q.push_back(x);
}
mx = max(mx, m[x]);
}
if (mx < k)puts("-1");
else {
sort(q.begin(), q.end());
int l = q[0], r = q[0];
mx = 0;
int ans = 0, last = q[0];
for (int i = 1; i < q.size(); i++) {
if (q[i] - q[i - 1] == 1) {
ans++;
} else {
ans = 0;
last = q[i];
}
if (ans > mx) {
mx = ans;
l = last;
r = q[i];
}
}
cout << l << " " << r << endl;
}
}
return 0;
}
题目大意: 一颗有根树,有n个顶点,一个字符串s,s又W和B组成,W表示该白色,B代表黑色,字符串中的每个字符表示每个节点的颜色,一个数组a,a2---an一共n个数,ai就是i节点的父节点,子树的黑色节点和白色节点数量相同则称该子树为平衡树,求该有根树的子树中有多少个平衡树.
思路:首先根据数组a建图,先预处理用-1表示白色,1表示黑色,如果该子树是平衡树的话,则节点值之和为0,dfs跑一遍,把每个子树的值赋给该子树的根节点,最后遍历所有节点,如果该节点的值为0,则ans++,最后输出ans即可。
(因为是多组输入,所以记得存图的数组和存节点值的数组清空)
#include<bits/stdc++.h>
using namespace std;
const int N=4e3+5;
vector<int>G[N];
int n;
int a[N],dp[N];
string s;
void dfs(int x)
{
for(int i=0;i < G[x].size();i++)
{
int next=G[x][i];
dfs(next);
dp[x] += dp[next];
}
}
int main()
{
int tt;
cin>>tt;
while(tt--)
{
cin>>n;
for(int i=0;i<=n;i++) G[i].clear();
for(int i=2;i<=n;i++)
{
cin>>a[i];
G[a[i]].push_back(i);
}
cin>>s;
s=' '+s;
memset(dp,0,sizeof dp);
for(int i=1;i<s.size();i++)
{
if(s[i]=='B') dp[i]=1;
else dp[i]=-1;
}
dfs(1);
int ans=0;
for(int i=1;i<=n;i++)
{
if(dp[i] == 0)ans++;
}
cout<<ans<<endl;
}
return 0;
}