F |
Beautiful Garden |
就是再在矩阵内部找到最大的那个不满足的矩阵,由于是对称的,所以只要只要找一个顶点就好,找到满足条件,即行最小,列最小的那个点,然后计算长和宽。大框和小框之间就是可以选择的范围,计算一下就好了。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2010;
int huiwen(string str)
{
string tmp = str;
reverse(str.rbegin(),str.rend());
for(int i=0;i<str.size();i++)
{
if(str[i]!=tmp[i])
{
return i+1;
}
}
return -1;
}
int main()
{
int T;
scanf("%d",&T);
for(int t=0;t<T;t++)
{
int n,m;
scanf("%d%d",&n,&m);
string mp[maxn];
vector<int> row,lie;
bool flag = true;
for(int i=1;i<=n;i++)
{
cin>>mp[i];
}
if(huiwen(mp[1])!=-1 || huiwen(mp[n])!=-1)
{
cout<<0<<endl;
flag = false;
continue;
}
for(int i=1;i<=n;i++)
{
if(mp[i][0]!=mp[i][m-1])
{
cout<<0<<endl;
flag = false;
break;
}
}
if(flag)
{
int pr = 0,pl = 0;
for(int i=2;i<n;i++)
{
if(huiwen(mp[i])!=-1)
{
row.push_back(i);
lie.push_back(huiwen(mp[i]));
if(mp[i]!=mp[n-i+1])
{
row.push_back(i);
for(int j=0;j<mp[i].size();j++)
{
if(mp[i][j]!=mp[n-i+1][j])
{
lie.push_back(j+1);
}
}
}
}
else
{
if(mp[i]!=mp[n-i+1])
{
row.push_back(i);
for(int j=0;j<mp[i].size();j++)
{
if(mp[i][j]!=mp[n-i+1][j])
{
lie.push_back(j+1);
}
}
}
}
}
sort(row.begin(),row.end());
sort(lie.begin(),lie.end());
//row[0]是行,lie[0]是列,坐标是(row[0],lie[0]),长和宽分别是 ((n/2)-row[0]+1)*2,((m/2)-lie[0]+1)*2
if(row.size()==0)
{
printf("%d\n",(n-2)*(m-2)/4);
}
else
{
int chang=((n/2)-row[0]+1)*2,kuan=((m/2)-lie[0]+1)*2;
int tt=(n-2)/2-(chang-2)/2;
int jj=(m-2)/2-(kuan-2)/2;
printf("%d\n",tt*jj);
}
}
}
return 0;
}
G |
Maximum Mode |
找最大的且唯一的众数,枚举答案,看所需的操作数和给的进行比较
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=1e5+5;
int a[maxn];
struct node{
int num,count;
}b[maxn];//num是数,count为出现的次数
bool cmp(node a, node b){
if(a.count==b.count){
return a.num<b.num;
}
else{
return a.count>b.count;
}
}
int main(){
int T;
scanf("%d",&T);
while(T--){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
scanf("%d",a+i);
}
sort(a+1,a+n+1);
memset(b,0,sizeof(node)*(n+1));
int now=1;
b[now].num=a[1],b[now].count=1;
for(int i=2;i<=n;++i){
if(a[i]==b[now].num){
b[now].count++;
}
else{
now++;
b[now].num=a[i];
b[now].count=1;
}
}
sort(b+1,b+now+1,cmp);//出现的次数从大到小,次数相同的情况下按值降序
bool pd=0;
int pre=0,ans=0;
for(int i=1;i<=now;++i){
if(b[i].count==b[i+1].count){
pre+=b[i].count;
continue;
}
ll temp=pre-(ll)(i-1)*(b[i].count-1);
//前面的i-1个数变成比b[i].num少出现一次最少需要删掉的数
if(temp>m)break;//这是不可能的
ans=max(ans,b[i].num);//如果可以更新最大值
pd=1;
pre+=b[i].count;
}
if(pd){
cout<<ans<<endl;
}
else{
cout<<-1<<endl;
}
}
return 0;
}