题目:A. Rainbow Dash, Fluttershy and Chess Coloring
轮流染色,相邻的格子不能相同颜色。手写一下4,5可知。
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 200005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
const int mod=1e9+7;
const int MAXlen=(5e5+10)*2;
double eps=1e-4;
ll gcd(ll a,ll b) {
if(!b)
return a;
else return gcd(b,a%b);
}
int main() {
int T;
scanf("%d",&T);
while(T--) {
int n;
scanf("%d",&n);
printf("%d\n",n/2+1);
}
return 0;
}
题意给了n个a[i]长度的木棍,q次操作每次加一个长度为x的木棍或者减一根,问能不能组成一个正方形和一个长方形或者正方形。
sums维护正方形的个数,sumr维护可以做两边的长方形边数,首选正方形。
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 200005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
const ll mod=998244353;
int a[100100];
int ifsq[100100]={0};
int book[100100]={0};
map<int,int>hh;
int main() {
int n,i,j;
int sums=0,sumr=0;
scanf("%d",&n);
for(i=1;i<=n;i++) {
scanf("%d",&a[i]);
book[a[i]]++;
if(book[a[i]]>=4) {
sums++;
book[a[i]]-=4;
continue;
}
}
for(i=1;i<=1e5;i++) {
if(book[i]>=2) {
sumr++;
}
}
int q;
scanf("%d",&q);
while(q--) {
char op;
getchar();
scanf("%c",&op);
int x;
scanf("%d",&x);
if(op=='+') {
if(book[x]==1) {
sumr++;
book[x]++;
}
else if(book[x]==3) {
sumr--;
sums++;
book[x]=0;
}
else {
book[x]++;
}
}
else {
if(book[x]==0) {
sums--;
sumr++;
book[x]=3;
}
else if(book[x]==2) {
book[x]--;
sumr--;
}
else {
book[x]--;
}
}
if((sums+(sumr/2)>=2)&&(sums>0))
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
题目:C. Pinkie Pie Eats Patty-cakes
题意:n的全排列的顺序,使得两种馅饼种类一样的之间的馅饼个数最多的最小值。
例如样例1的排列方式:1 7 1 6 4 4 6–> 1 6 4 7 1 6 4
最多个数的依次列入,保证了他们之间的个数同步上升,剩余的间隔中插入剩余的数字。之后求最小的。
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PP;
const int MAX_len=8e7+2;
const ll mod=4294967296;
int book[100100];
int a[100100];
int main()
{
int T;
scanf("%d",&T);
while(T--) {
int n,i,j;
scanf("%d",&n);
for(i=0;i<=n+1;i++)
book[i]=0;
int MAX=1;
for(i=1;i<=n;i++) {
scanf("%d",&a[i]);
book[a[i]]++;
MAX=max(MAX,book[a[i]]);
}
int sum=0;
for(i=1;i<=n;i++) {
if(book[i]==MAX)
sum++;
}
int t1=n-sum*MAX;
int ans=t1/(MAX-1)+(sum-1);
printf("%d\n",ans);
}
return 0;
}
题意:要求题中所述菱形的个数。
举个栗子:
可以发现第二幅图的中间的d有几种组成‘菱形’的方式,长度为1的1种,长度为2的一种,长度为3的一种,以他为中心的有3种方法构成有效的‘菱形’。
dp[i][j]:即是以i,j为中心构成有效情况的个数,最后相加。
但是不能直接进行dp,需要完善各个方向,l[i][j]:表示i,j左边相同字母的个数,维护,同理r[][]。这样以i,j为中心左右两边的最长长度就是min(l[i][j],r[i][j])。之后还是需要处理,同理分析上下方向的格子,
如果u[i][j]==u[i-1][j]的情况说明可以向延续,上头分析了个数即是min(l[i][j],r[i][j])与u[i-1][j]+1的最小,同理下方。
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PP;
const int MAX_len=8e7+2;
const ll mod=4294967296;
char s[2010][2010];
int l[2010][2010],r[2010][2010],u[2010][2010],d[2010][2010];
int main()
{
int n,m,i,j;
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++) {
getchar();
for(j=1;j<=m;j++)
scanf("%c",&s[i][j]);
}
for(i=1;i<=n;i++) {
for(j=1;j<=m;j++) {
l[i][j]=1;
if(s[i][j]==s[i][j-1]) {
l[i][j]=max(l[i][j],l[i][j-1]+1);
}
}
for(j=m;j>=1;j--) {
r[i][j]=1;
if(s[i][j]==s[i][j+1]) {
r[i][j]=max(r[i][j],r[i][j+1]+1);
}
}
}
for(i=1;i<=m;i++) {
for(j=1;j<=n;j++) {
u[j][i]=1;
if(s[j][i]==s[j-1][i]) {
int temp=min(l[j][i],r[j][i]);
u[j][i]=min(u[j-1][i]+1,temp);
}
}
for(j=n;j>=1;j--) {
d[j][i]=1;
if(s[j][i]==s[j+1][i]) {
int temp=min(l[j][i],r[j][i]);
d[j][i]=min(d[j+1][i]+1,temp);
}
}
}
ll ans=0;
for(i=1;i<=n;i++) {
for(j=1;j<=m;j++)
ans+=min(u[i][j],d[i][j]);//cout<<min(u[i][j],d[i][j])<<" ";
// cout<<endl;
}
printf("%lld",ans);
return 0;
}