传送门
直接计算v的二进制中1的个数就行了(貌似是某场cf的一道题)
#include <bits/stdc++.h>
#define ll long long
#define N 1010
using namespace std;
int main()
{
#ifndef ONLINE_JUDGE
// freopen("1.txt", "r", stdin);
#endif
ll t, n , ans;
cin >> n;
while(n--)
{
cin >> t;
ans = 0;
while(t)
{
ans += t%2;
t >>= 1;
}
cout << ans << endl;
}
return 0;
}
传送门
直接重载一下<就行了,然后排序一下
#include <bits/stdc++.h>
#define ll long long
#define N 1010
using namespace std;
struct node{
ll a, b;
friend bool operator < (node aaa, node bbb)
{
if (aaa.a == bbb.a) return aaa.b > bbb.b;
return aaa.a < bbb.a;
}
}aa[N];
int main()
{
#ifndef ONLINE_JUDGE
freopen("1.txt", "r", stdin);
#endif
ll n, k, i;
while(cin >> n >> k)
{
for (i = 0; i < n; i++)
cin >> aa[i].a >> aa[i].b;
sort(aa, aa+n);
for (i = n-1; i >= 0; i--)
{
if (aa[i].b >= k)
cout << aa[i].a << " " << aa[i].b << endl;
}
}
return 0;
}
传送门
比赛的时候我直接暴力,然后加上一堆break就过了
#include <bits/stdc++.h>
#define ll long long
#define N 210
using namespace std;
char mm[N][N];
int x, y;
int fun(int x1, int y1, int x2, int y2)
{
for (int i = x1; i <= x2; i++)
{
if (mm[i][y1] == 'X' || mm[i][y2] == 'X') return -1;
// if ( mm[i][y2] == 'X') return -2;
}
for (int i = y1; i <= y2; i++)
{
if (mm[x1][i] == 'X' || mm[x2][i] == 'X') return -1;
// if (mm[x2][i] == 'X') return -4;
}
return (x2-x1+1)*(y2-y1+1);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("1.txt", "r", stdin);
#endif
int i1, i2, j1, j2, k, n, m, ans, s1, s2;
bool flag;
while(cin >> n >> m)
{
for (int i = 0; i < n; i++)
cin >> mm[i];
ans = 0;
for (i1 = 0; i1 < n; i1++)
{
for (j1 = 0; j1 < m; j1++)
{
flag = false;
for (s2 = j1; s2 < m; s2++)
if (mm[i1][s2] == 'X') break;
for (s1 = i1; s1 < n; s1++)
if (mm[s1][j1] == 'X') break;
for (i2 = s1 - 1; i2 >= i1; i2--)
{
for (j2 = s2 - 1; j2 >= j1; j2--)
{
if (flag)
{
if ((x-i2)*(y-j1+1) < (j2-y)*(i2-i1+1))
{
k = fun(i1, j1, i2, j2);
if (k != -1)
{
// cout << i1 << ' ' << j1 << ' ' << i2 << ' ' << j2 << ' ' << k << endl;
ans = max(ans, k);
x = i2;
y = j2;
break;
}
}
else break;
}
k = fun(i1, j1, i2, j2);
if (k != -1)
{
// cout << i1 << ' ' << j1 << ' ' << i2 << ' ' << j2 << ' ' << k << endl;
ans = max(ans, k);
x = i2;
y = j2;
flag = true;
break;
}
}
}
}
}
cout << ans << endl;
}
return 0;
}
然而标程是这样的
先求二维前缀和
然后先遍历长方形的两个竖着的边,然后在遍历长方形的上边。
当last为-1 的时候表示还没找到长方形的上边,
当last不等于-1时,last的值就是当前已经找到的上边
#include <stdio.h>
#include <string.h>
char mm[210][210];
int a[210][210];
int main()
{
int n, m, i, j, k, ans;
while(scanf("%d%d", &n, &m) != EOF)
{
for (i = 1; i <= n; i++)
scanf("%s", mm[i]+1);
memset(a, 0, sizeof(a));
for (i = 1; i <= n; i++)
{
for (j = 1; j <= m; j++)
{
a[i][j] = a[i-1][j]+a[i][j-1]-a[i-1][j-1];
if (mm[i][j] == 'X')
{
a[i][j]++;
}
}
}
int last = -1, t, ans = 0;
for (i = 1; i <= m; i++)
{
for (j = i; j <= m; j++)
{
last = -1;
for (k = 1; k <= n; k++)
{
if (mm[k][j] == 'X' || mm[k][i] == 'X')
{
last = -1;
continue;
}
t = a[k][j]-a[k][i-1]-a[k-1][j]+a[k-1][i-1];
if (!t)
{
if (last == -1)
{
if (ans < j-i+1) ans = j-i+1;
last = k;
}
else
{
if (ans < (j-i+1)*(k-last+1)) ans = (j-i+1)*(k-last+1);
}
}
}
}
}
printf("%d\n", ans);
}
return 0;
}
这个一个学长的做法
暴力+dp判断是否能够构成边框
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
#define MAX_N 210
int ans;
int n,m;
char strMap[MAX_N][MAX_N];
int l[MAX_N][MAX_N];
int u[MAX_N][MAX_N];
int r[MAX_N][MAX_N];
int d[MAX_N][MAX_N];
bool IsOK(int x,int y,int w,int h)
{
int lx,ly;
lx=x-w+1;
ly=y-h+1;
if(r[ly][lx]>=w && l[y][x]>=w && d[ly][lx]>=h && u[y][x]>=h) return true;
return false;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
ans=0;
memset(strMap,0,sizeof(strMap));
for(int i=1;i<=n;i++) scanf("%s",&strMap[i][1]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(strMap[i][j]=='X')
{
l[i][j]=0;
u[i][j]=0;
}
else
{
l[i][j]=l[i][j-1]+1;
u[i][j]=u[i-1][j]+1;
}
}
for(int i=n;i>=1;i--)
for(int j=m;j>=1;j--)
{
if(strMap[i][j]=='X')
{
r[i][j]=0;
d[i][j]=0;
}
else
{
r[i][j]=r[i][j+1]+1;
d[i][j]=d[i+1][j]+1;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int k,l;
for(k=1;k+i-1<=n;k++) if(strMap[i+k-1][j]=='X') break;
for(l=1;l+j-1<=m;l++) if(strMap[i][l+j-1]=='X') break;
for(int ii=k-1;ii>=1;ii--)
for(int jj=l-1;jj>=1;jj--)
{
if(IsOK(j+jj-1,i+ii-1,jj,ii))
{
ans=max(ans,jj*ii);
break;
}
}
}
}
printf("%d\n",ans);
}
return 0;
}