//话说今天又有场上看题解的, 真TMD的恶心;
A:水题, 不必多说;
B:其实是可以构造的, 这个题场上没出
1、颜色排序, 按最多, 最少, 次多, 次少填入。
另外, 先奇数,不行再偶数;
队友后来补的
构造:
#include<bits/stdc++.h>
using namespace std;
int num[60];
struct xx{
int ID,num;
bool operator <(const xx&rhs) const {
return num>rhs.num;
}
}Y[60],YY[60];
int YYY[60];
int a[30][30];
int main()
{
int t,kase=0;scanf("%d",&t);
while(t--){
memset(a,-1,sizeof(a));
memset(Y,0,sizeof(Y));
memset(YY,0,sizeof(YY));
int n,m,k;scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<k;i++) { scanf("%d",&Y[i].num); Y[i].ID=i; }
sort(Y,Y+k);
// printf("####:");
// for(int i=0;i<k;i++) printf("%d ",Y[i].num); printf("\n");
int y1=0,y2=k-1;//printf("***:");
for(int i=0;i<k;i++)
{
if(i%2==0)
YY[i]=Y[y1++];
else YY[i]=Y[y2--];
//printf("%d ",YY[i].num);
//printf("ID[%d] ",YY[i].ID);
}//printf("\n");
int J=0;
for(int i=0;i<k;i++) {
while(YY[i].num--)
YYY[J++] = YY[i].ID;}
// printf("YYYY:");
// for(int i=0;i<n*m;i++) printf("%d ",YYY[i]); printf("\n");
int K=0;
for(int i=0;i<n;i++){
if( !( i&1) )
{
for(int j=0;j<m;j+=2) a[i][j]=YYY[K++];
}
else
{ for(int j=1;j<m;j+=2) a[i][j]=YYY[K++]; }
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++)
{
if(a[i][j]==-1){
a[i][j]=YYY[K++];
}
}
}
int flag=1;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++)
{
if(j+1<m&&a[i][j]==a[i][j+1]) { flag=0; break; }
if(j-1>=0&&a[i][j]==a[i][j-1]) { flag=0; break; }
if(i+1<n&&a[i][j]==a[i+1][j]) { flag=0; break; }
if(i-1>=0&&a[i][j]==a[i-1][j]) { flag=0; break; }
}
if(flag==0 ) break;
}
if(flag==0){
memset(a,-1,sizeof(a));
flag=1;
int K=0;
for(int i=0;i<n;i++){
if( !( i&1) )
{
for(int j=1;j<m;j+=2) a[i][j]=YYY[K++];
}
else
{ for(int j=0;j<m;j+=2) a[i][j]=YYY[K++]; }
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++)
{
if(a[i][j]==-1){
a[i][j]=YYY[K++];
}
}
}
flag=1;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++)
{
if(j+1<m&&a[i][j]==a[i][j+1]) { flag=0; break; }
if(j-1>=0&&a[i][j]==a[i][j-1]) { flag=0; break; }
if(i+1<n&&a[i][j]==a[i+1][j]) { flag=0; break; }
if(i-1>=0&&a[i][j]==a[i-1][j]) { flag=0; break; }
}
if(flag==0 ) break;
}
}
if(flag==0&&0){
memset(a,-1,sizeof(a));
flag=1;
int K=0;
for(int j=0;j<m;j++){
if( !( j&1) )
{
for(int i=1;i<n;i+=2) a[i][j]=YYY[K++];
}
else
{ for(int i=0;i<n;i+=2) a[i][j]=YYY[K++]; }
}
for(int j=0;j<m;j++){
for(int i=0;i<n;i++)
{
if(a[i][j]==-1){
a[i][j]=YYY[K++];
}
}
}
flag=1;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++)
{
if(j+1<m&&a[i][j]==a[i][j+1]) { flag=0; break; }
if(j-1>=0&&a[i][j]==a[i][j-1]) { flag=0; break; }
if(i+1<n&&a[i][j]==a[i+1][j]) { flag=0; break; }
if(i-1>=0&&a[i][j]==a[i-1][j]) { flag=0; break; }
}
if(flag==0 ) break;
}
}
if(flag==0&&0){
memset(a,-1,sizeof(a));
flag=1;
int K=0;
for(int j=0;j<m;j++){
if( !( j&1) )
{
for(int i=0;i<n;i+=2) a[i][j]=YYY[K++];
}
else
{ for(int i=1;i<n;i+=2) a[i][j]=YYY[K++]; }
}
for(int j=0;j<m;j++){
for(int i=0;i<n;i++)
{
if(a[i][j]==-1){
a[i][j]=YYY[K++];
}
}
}
flag=1;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++)
{
if(j+1<m&&a[i][j]==a[i][j+1]) { flag=0; break; }
if(j-1>=0&&a[i][j]==a[i][j-1]) { flag=0; break; }
if(i+1<n&&a[i][j]==a[i+1][j]) { flag=0; break; }
if(i-1>=0&&a[i][j]==a[i-1][j]) { flag=0; break; }
}
if(flag==0 ) break;
}
}
printf("Case #%d:\n",++kase);
if(flag) {
printf("YES\n");
// printf("^^^^^^\n");
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(j==0)
printf("%d",a[i][j]+1);
else printf(" %d",a[i][j]+1);
}
printf("\n");
}
// printf("^^^^^^\n");
}
else printf("NO\n");
}
return 0;
}
2、dfs回溯+剪枝;
我当时没想到这个剪枝, 就一直在想构造了;
剪枝还是应该由她的这个主要性质决定的吧;
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 5 + 5;
int res[maxn][maxn];
int cnt[maxn * maxn];
int n, m, k;
int flog;
int ok(int i, int j, int kk)
{
if(i-1 >= 1)
if(res[i-1][j] != -1 && res[i-1][j] == kk) return 0;
if(i+1 <= n)
if(res[i+1][j] != -1 && res[i+1][j] == kk) return 0;
if(j-1 >= 1)
if(res[i][j-1] != -1 && res[i][j-1] == kk) return 0;
if(j+1 <= m)
if(res[i][j+1] != -1 && res[i][j+1] == kk) return 0;
return 1;
}
void dfs(int i, int j, int v)
{
if(i==n && j==m) flog = true;
if(flog) return ;
for(int i = 1; i <= k; ++i)
if((v+1)/2 < cnt[i]) return ;
for(int kk = 1; kk <= k; ++kk)
{
if(!cnt[kk]) continue;
if(j==m)
{
if(ok(i+1, 1, kk))
{
--cnt[kk];
res[i+1][1] = kk;
dfs(i+1, 1, v-1);
if(flog) return ;
res[i+1][1] = -1;
++cnt[kk];
}
}
else
{
if(ok(i, j+1, kk))
{
--cnt[kk];
res[i][j+1] = kk;
dfs(i, j+1, v-1);
if(flog) return ;
res[i][j+1] = -1;
++cnt[kk];
}
}
}
return ;
}
int main()
{
int T;
scanf("%d", &T);
int kase = 0;
while(T--)
{
printf("Case #%d:\n", ++kase);
scanf("%d%d%d", &n, &m, &k);
memset(cnt,0,sizeof(cnt));
memset(res,-1,sizeof(res));
for(int i = 1; i <= k; ++i) scanf("%d", &cnt[i]);
flog = false;
dfs(1, 0, n*m);
if(flog)
{
cout << "YES" << endl;
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= m; ++j)
{
if(j==1) printf("%d", res[i][j]);
else printf(" %d", res[i][j]);
}
printf("\n");
}
}
else cout << "NO" << endl;
}
return 0;
}
H:队友补的dp
#include<bits/stdc++.h>
using namespace std;
long long dp[3][1100000];
int main()
{
int T;
cin>>T;
int kase=0;
while(T--)
{
memset(dp,0,sizeof(dp));
int n, m;
cin>>n>>m;
int a[50];
for(int i=1;i<=n;i++)
cin>>a[i];
dp[0][0]=1;
for(int i=1;i<=n;i++)
for(int j=0;j<1000000;j++)
dp[i%2][j]=dp[(i-1)%2][j]+dp[(i-1)%2][j^a[i]];
long long sum=0;
for(int i=m;i<1000000;i++)
sum+=dp[n%2][i];
cout<<"Case #"<<++kase<<": ";
printf("%I64d\n",sum);
}
return 0;
}
I:几何模板
#include<bits/stdc++.h>
using namespace std;
const double eps=1e-8, Pi=acos(-1.0);
struct Point{
double x, y;
Point (double _x=0, double _y=0)
{
x=_x;
y=_y;
}
Point operator-(const Point &ne) const{
return Point (x-ne.x,y-ne.y);
}
};
struct circle
{
Point o;
double r;
circle (){}
circle(Point _o, double _r)
{
o=_o;
r=_r;
}
};
inline double dmult(Point a, Point b)
{
return a.x*b.x+a.y*b.y;
}
inline double lenth(Point a)
{
return sqrt(dmult(a,a));
}
inline double dist (Point a, Point b)
{
return lenth(b-a);
}
double area(circle a, circle b)
{
double d=dist(a.o,b.o), r1=a.r, r2=b.r, r;
if(r1+r2<=d)
return 0.0;
else if(fabs(r1-r2)>=d)
{
r=min(r1,r2);
return Pi*r*r;
}
else {
double a1=(r1*r1+d*d-r2*r2)/(2*r1*d);
double a2=(r2*r2+d*d-r1*r1)/(2*r2*d);
a1=2*acos(a1);
a2=2*acos(a2);
return (r1*r1*(a1-sin(a1))+r2*r2*(a2-sin(a2)))*0.5;
}
}
using namespace std;
int main()
{
int T;
cin>>T;
int kase=0;
while(T--)
{
double r1, r2;
scanf("%lf%lf", &r1, &r2);
double x1, y1, x2, y2;
scanf("%lf%lf%lf%lf", &x1,&y1,&x2,&y2);
Point a(x1,y1), b(x2,y2);
circle a1(a,r1), a2(a,r2), b1(b,r1), b2(b,r2);
printf("Case #%d: ",++kase);
if(x1==x2&&y1==y2)
{
printf("%.6lf\n",Pi*(r2*r2-r1*r1)*1.0);
}
else
{
double t1, t2, t3;
t1=area(a1,b1);
t2=area(a2,b2);
t3=area(a1,b2);
printf("%.6lf\n",(t1-2*t3+t2)*1.0);
}
}
return 0;
}
K:贪心
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string.h>
#include<vector>
#include<list>
#include<algorithm>
using namespace std;
const int maxn = 1e6 + 5;
vector<int> res;
int cnt[maxn];
int main()
{
int T;
cin >> T;
int kase =0;
while(T--)
{
res.clear();
memset(cnt,0,sizeof(cnt));
int n;
cin >> n;
for(int i = 0; i < n; ++i)
{
int x;
scanf("%d", &x);
res.push_back(x);
}
int k =0;
for(int i = n; i >= 1; --i)
{
if(cnt[res.back()])
{
i+=1;
res.pop_back();
continue;
}
cnt[i] = 1;
if((int)res.size() != 0 && res.back() == i)
{
res.pop_back();
}
else if((int)res.size() != 0 && res.back() != i)
{
++k;
}
}
printf("Case #%d: %d\n", ++kase, k);
}
return 0;
}