现场只写出来两道。
题意:找到数组任意一个子集的和是偶数
题解:贪心,找到任意一个偶数或者两个奇数就可以了。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <math.h>
using namespace std;
#define MAX 50005
typedef long long int _int;
int a[1005];
int res[1005];
int main()
{
int t;
scanf("%d",&t);
int x=0;
while(x<t)
{
x++;
int n;
scanf("%d",&n);
int m=0;
int tag=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
if(!(a[i]&1)&&tag==0)
{
m=0;
res[m++]=i;
tag=1;
}
if(a[i]&1&&tag==0&&(m==0||m==1))
{
res[m++]=i;
if(m==2)
tag=1;
}
}
if(m==1&&a[res[m-1]]&1) {
printf("-1
");
continue;
}
printf("%d
",m);
for(int i=0;i<m;i++)
{
if(i==m-1)
printf("%d
",res[i]+1);
else
printf("%d ",res[i]+1);
}
}
return 0;
}
题意:题意是这样的,给你一个列向量b和行向量a,二者相乘ab,是一个nm的0,1矩阵,问你在这个矩阵里,有多少个不同的矩形,都有1组成,面积为k
题解:1. 先考虑在一个全是1的nm矩阵中,含有多少个不同的pq的矩形,p<n && q<m
p ,n是长,m,q是宽。那么 num = (n-p+1)(m-q+1);
在p!=q的情况将p,q调换一下,再计算一下。
然后就考虑nm的矩阵的情况,a*b,的过程是b作为新矩阵的行,比如:
b={1,1,1}
a = {1,0,1}
1 1 1 a[0]=1
0 0 0 a[1]=0
1 1 1 a[2]=1
2. 考虑b中有多少个连续的1:宽
然后根据a中有多少个连续的1:长
组成很多个矩形,每个矩形都计算一下
3.k 是面积,要计算出所有可能的组合矩形
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <math.h>
using namespace std;
#define MAX 50005
typedef long long int _int;
int a[MAX];
int b[MAX];
int c[MAX];
int d[MAX];
int e[MAX];
_int f[MAX];
int p,l;
_int ans;
void fun(int y)
{
if(f[y]==-1)
{
f[y]=0;
for(int j=0;j<l;j++)
{
int height = y;
int width = e[j];
for(int jj=0;jj<p;jj++)
{
int h = c[jj];
int w = d[jj];
if(height>=h&&width>=w) {
int num1 = height - h + 1;
int num2 = width - w + 1;
f[y]+=(_int)num1*(_int)num2;
}
if(h!=w) {
h = d[jj];
w = c[jj];
if (height >= h && width >= w) {
int num1 = height - h + 1;
int num2 = width - w + 1;
f[y]+=(_int)num1*(_int)num2;
}
}
}
}
ans+=f[y];
} else
{
ans+=f[y];
}
}
int main()
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
for(int i=0;i<m;i++)
{
scanf("%d",&b[i]);
}
p=0;
for(int i=1;i*i<=k;i++)
{
if(k%i==0)
{
c[p]=i;
d[p]=k/i;
p++;
}
}
l=0;
int x=0;
for(int i=0;i<m;i++)
{
if(b[i]==1)
{
x++;
}
else
{
if(x!=0) {
e[l++] = x;
x = 0;
}
}
}
if(x!=0)
e[l++]=x;
memset(f,-1,sizeof(f));
ans=0;
int y=0;
for(int i=0;i<n;i++)
{
if(a[i]==1)
{
y++;
}
else
{
if(y!=0)
{
fun(y);
}
y=0;
}
}
if(y!=0)
fun(y);
printf("%lld
",ans);
}
题解:贪心,利用栈,想一想就知道怎么写了。挺简单的
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <math.h>
using namespace std;
#define MAX 1000005
typedef long long int _int;
int n;
char s[MAX];
int top;
int main()
{
scanf("%d
",&n);
int tag=0;
top=0;
int res=0;
int ans=0;
int tag2=0;
char x;
for(int i=0;i<n;i++)
{
scanf("%c",&x);
if(top==0)
{
if (x == ')')
{
tag++;
}
s[top++]=x;
}
else
{
if(x=='(')
{
if(tag!=0)
tag2++;
s[top++]=x;
if(tag2==tag&&tag2!=0)
{
ans+=tag+tag2+res;
tag=0;
tag2=0;
top=0;
res=0;
}
}
else
{
if(tag!=0)
{
if(s[top-1]=='(')
{
top--;
if(tag2!=0)
tag2--;
res+=2;
}
else if(s[top-1]==')')
{
s[top++]=x;
tag++;
}
} else
{
if(s[top-1]=='(')
{
top--;
if(top==0)
tag=0;
}
}
}
}
}
if(tag==tag2&&tag!=0)
{
ans+=(tag+tag2);
top=0;
}
if(top!=0)
printf("-1
");
else
printf("%d
",ans);
}