Codeforces Round #243
CF 243 DIV1 & DIV2
DIV2的A和B都太水,直接暴力搞就可以的。
DIV2A
/* ***********************************************
Author :kuangbin
Created Time :2014/4/30 19:42:51
File Name :E:\2014ACM\Codeforces\CF243\DIV2_A.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std; int a[];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,s;
while(scanf("%d%d",&n,&s) == )
{
for(int i = ;i < n;i++)
scanf("%d",&a[i]);
sort(a,a+n);
int ans = ;
for(int i = ;i < n-;i++)
ans += a[i];
if(ans <= s)printf("YES\n");
else printf("NO\n");
}
return ;
}
DIV2B
/* ***********************************************
Author :kuangbin
Created Time :2014/4/30 19:53:16
File Name :E:\2014ACM\Codeforces\CF243\DIV2_B.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int MAXN = ;
int a[MAXN][MAXN];
int b[MAXN][MAXN]; int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,m;
while(scanf("%d%d",&n,&m) == )
{
for(int i = ;i < n;i++)
for(int j = ;j < m;j++)
scanf("%d",&a[i][j]);
int tmp = n;
if(tmp%)
{
printf("%d\n",n);
continue;
}
for(int i = ;i < n;i++)
for(int j = i+;j < n;j++)
{
int tt = ;
for(int k = ;k < m;k++)
if(a[i][k] != a[j][k])
{
tt = ;
break;
}
b[i][j] = b[j][i] = tt;
}
for(int t = ;t <= n;t++)
{
int tmp = t;
while(tmp < n)tmp *= ;
if(tmp != n)continue;
bool flag = true;
int mir = t;
while(mir != n)
{
for(int i = ;i < mir;i++)
if(b[i][*mir--i] == )
{
flag = false;
break;
}
if(!flag)break;
mir *= ;
}
if(flag)
{
printf("%d\n",t);
break;
}
}
}
return ;
}
DIV1A
题意:
给出了n(1<=n<=200)的数列a, 让你最多交换k(1<=k<=10)次,使得最大连续子序列的和最大。输出最大的连续子序列和。
因为n比较小,直接暴力枚举区间,然后将这个区间的k个小的,换成比较大的。
代码君:
/* ***********************************************
Author :kuangbin
Created Time :2014/4/27 23:29:36
File Name :E:\2014ACM\Codeforces\CF243\A.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std; const int MAXN = ;
int a[MAXN];
int b[MAXN];
int c[MAXN];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,k;
while(scanf("%d%d",&n,&k) == )
{
for(int i = ;i <= n;i++)
scanf("%d",&a[i]);
int ans = -;
for(int l = ;l <= n;l++)
for(int r = l;r<= n;r++)
{
int cnt1 = ;
int cnt2 = ;
for(int i = ;i <= n;i++)
{
if(i >= l && i <= r)
b[cnt1++] = a[i];
else c[cnt2++] = a[i];
}
sort(b,b+cnt1);
sort(c,c+cnt2);
reverse(c,c+cnt2);
int tt = min(cnt1,cnt2);
tt = min(tt,k);
for(int i = ;i < cnt1;i++)
b[i] += b[i-];
for(int i = ;i < cnt2;i++)
c[i] += c[i-]; for(int i = ;i <= tt;i++)
{
int num1 = i;
int num2 = i;
int tmp = b[cnt1-];
if(num1 > )tmp -= b[num1-];
if(num2 > )tmp += c[num2-];
ans = max(ans,tmp);
} }
printf("%d\n",ans);
}
return ;
}
DIV1B
给出一个n*m的01矩阵, 让你最多改变k个里面的值(0变1,1变0), 使得0、1的连通分量是矩阵。输出最少步数
1 ≤ n, m ≤ 100; 1 ≤ k ≤ 10
题解:
如果01连通分量是矩形,
那么矩形一定是这样的:
0101010
1010101
0101010
1010101
(上面的01代表子矩阵块)。
也就是每一行要么是相同,要么是相反的。
如果n>k, 肯定有一行是不能改变的,那么枚举这一行,然后其余的要么变相同,要么变相反,看最少的步数。
如果n<k ,那么可以枚举第一列的状态(2^k), 然后其余列变成和第一列相同或者相反。
/* ***********************************************
Author :kuangbin
Created Time :2014/4/29 11:30:04
File Name :E:\2014ACM\Codeforces\CF243\B.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int MAXN = ;
int a[MAXN][MAXN]; int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,m,k;
while(scanf("%d%d%d",&n,&m,&k) == )
{
for(int i = ;i < n;i++)
for(int j = ;j < m;j++)
scanf("%d",&a[i][j]);
int ans = ;
if(n > k)
{
for(int t = ;t < n;t++)
{
int tmp = ;
for(int i = ;i < n;i++)
{
int cnt = ;
for(int j = ;j < m;j++)
if(a[i][j] == a[t][j])
cnt++;
tmp += min(cnt,m-cnt);
}
ans = min(tmp,ans);
}
}
else
{
for(int t = ;t < (<<n);t++)
{
int tmp = ;
for(int j = ;j < m;j++)
{
int cnt = ;
for(int i = ;i < n;i++)
if(a[i][j] == ((t>>i)&))
cnt++;
tmp += min(cnt,n-cnt);
}
ans = min(tmp,ans);
}
}
if(ans <= k)printf("%d\n",ans);
else printf("-1\n");
}
return ;
}
DIV1C
题意:比较长,自己看题目吧
1 ≤ s ≤ 3·10^5; 10^3 ≤ e ≤ 10^4
所以第一个操作最多是300次.
用dp[i][j] 表示a序列消掉了前i个,消了j次,b序列的最小位置。
转移的时候,dp[i][j], 其实就是dp[0][j-1],dp[1][j-1],......dp[i-1][j-1]中最小的,下一个a[i]的位置。
用个数组标记下位置,因为那个最小值是递减的。
/* ***********************************************
Author :kuangbin
Created Time :2014/4/29 22:16:58
File Name :E:\2014ACM\Codeforces\CF243\C.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std; int dp[][];
int a[];
int b[];
vector<int>vb[];
int next[]; int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,m,s,e;
while(scanf("%d%d%d%d",&n,&m,&s,&e) == )
{
for(int i = ;i < n;i++)
scanf("%d",&a[i]);
for(int i = ;i < m;i++)
scanf("%d",&b[i]);
for(int i = ; i <= ;i++)
vb[i].clear();
for(int i = ;i < m;i++)
vb[b[i]].push_back(i);
for(int i = ; i <= ;i++)
vb[i].push_back(m);
int k = s/e;
int ans = ;
for(int i = ;i <= k;i++)
{
for(int j = ;j <= ;j++)
next[j] = vb[j].size() - ;
int mm = m;
if(i == )mm = -;
for(int j = ;j < n;j++)
{
while(next[a[j]] > && vb[a[j]][next[a[j]]-] > mm)
next[a[j]]--;
dp[i][j] = vb[a[j]][next[a[j]]];
if(i > )mm = min(mm,dp[i-][j]);
if(dp[i][j] < m && j + dp[i][j] + + e*i <= s)
ans = max(ans,i);
}
}
printf("%d\n",ans);
}
return ;
}
DIV1D
题意,给了n个点, 让你求出有多少个平行于坐标轴的正方形,四个点都在给定的点上。
可以使用hash或者二分查找,快速判断一个点是不是存在。
枚举x坐标,如果x的个数<sqrt(n), 那么两重循环枚举这个x的点,确定边长,然后进行hash判断是不是存在。
如果x的个数>=sqrt(n), 那么枚举下所有的点,来确定下边长,然后进行hash判断
/* ***********************************************
Author :kuangbin
Created Time :2014/4/30 18:27:57
File Name :E:\2014ACM\Codeforces\CF243\D.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std; vector<int>vx[];
bool has(int x,int y)
{
if(x > || y > || x < || y < )return false;
return binary_search(vx[x].begin(),vx[x].end(),y);
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;
while(scanf("%d",&n) == )
{
for(int i = ;i <= ;i++)
vx[i].clear();
int x,y;
for(int i = ;i < n;i++)
{
scanf("%d%d",&x,&y);
vx[x].push_back(y);
}
for(int i = ;i <= ;i++)
sort(vx[i].begin(),vx[i].end());
int ans = ;
int bd = (int)sqrt(1.0*n);
for(int x = ;x <= ;x++)
if(vx[x].size())
{
if(vx[x].size() < bd)
{
for(int i = ;i < vx[x].size();i++)
for(int j = i+;j < vx[x].size();j++)
{
int d = vx[x][j] - vx[x][i];
if(has(x+d,vx[x][i]) && has(x+d,vx[x][j]))
ans++;
}
}
else
{
for(int xx = x+;xx <= ;xx++)
for(int i = ;i < vx[xx].size();i++)
{
int yy = vx[xx][i];
int d = xx - x;
if(has(x,yy) && has(x,yy+d) && has(xx,yy+d))
ans++;
}
}
}
printf("%d\n",ans);
}
return ;
}
DIV1E
经典的DP题
使用dp[i][j] 表示最多j个不相交区间,最靠左的j个不相交区间的最后一个区间位置是i.
如果dp[i][j] -> dp[ii][j+1]的话,2^( (ii-i)*i ) 这种是横跨的区间,可选可不选。
(ii-i)个区间是最少要选择一个的, 2^(ii-i)-1
然后就可以得出来了。
/* ***********************************************
Author :kuangbin
Created Time :2014/4/28 0:47:23
File Name :E:\2014ACM\Codeforces\CF243\E.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int MOD = 1e9+;
const int MAXN = ;
int dp[MAXN][MAXN];//dp[i][j]表示有j个不相交区间,最左的最后一个区间的位置是i
void Add(int &a,int b)
{
a += b;
while(a >= MOD)a -= MOD;
}
int two[*];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,k;
two[] = ;
for(int i = ;i <= *;i++)
two[i] = *two[i-]%MOD;
while(scanf("%d%d",&n,&k) == )
{
memset(dp,,sizeof(dp));
dp[][] = ;
for(int i = ;i < n;i++)
for(int j = ;j < k;j++)
if(dp[i][j])
{
for(int ii = i+;ii <= n;ii++)
{
long long tmp = two[i*(ii - i)];
tmp = tmp*(two[ii-i]-)%MOD;
Add(dp[ii][j+],tmp*dp[i][j]%MOD);
}
}
int ans = ;
for(int i = ;i <= n;i++)
Add(ans,(long long)dp[i][k]*two[i*(n-i)]%MOD);
printf("%d\n",ans);
}
return ;
}
Codeforces Round #243的更多相关文章
- Codeforces Round #243 (Div. 2) B(思维模拟题)
http://codeforces.com/contest/426/problem/B B. Sereja and Mirroring time limit per test 1 second mem ...
- Codeforces Round #243 (Div. 1) A题
http://codeforces.com/contest/425/problem/A 题目链接: 然后拿出这道题目是很多人不会分析题目,被题目吓坏了,其中包括我自己,想出复杂度,一下就出了啊!真是弱 ...
- Codeforces Round #243 (Div. 2) Problem B - Sereja and Mirroring 解读
http://codeforces.com/contest/426/problem/B 对称标题的意思大概是.应当指出的,当线数为奇数时,答案是线路本身的数 #include<iostream& ...
- Codeforces Round #243 (Div. 2) C. Sereja and Swaps
由于n比较小,直接暴力解决 #include <iostream> #include <vector> #include <algorithm> #include ...
- Codeforces Round #243 (Div. 2) B. Sereja and Mirroring
#include <iostream> #include <vector> #include <algorithm> using namespace std; in ...
- Codeforces Round #243 (Div. 2) A. Sereja and Mugs
#include <iostream> #include <vector> #include <algorithm> #include <numeric> ...
- Codeforces Round #243 (Div. 2) C. Sereja and Swaps(优先队列 暴力)
题目 题意:求任意连续序列的最大值,这个连续序列可以和其他的 值交换k次,求最大值 思路:暴力枚举所有的连续序列.没做对是因为 首先没有认真读题,没看清交换,然后,以为是dp或者贪心 用了一下贪心,各 ...
- Codeforces Round #243 (Div. 2) A~C
题目链接 A. Sereja and Mugs time limit per test:1 secondmemory limit per test:256 megabytesinput:standar ...
- Codeforces Round #243 (Div. 1)-A,B,C-D
此CF真是可笑.. . 由于早晨7初始点,因此,要做好CF时间已经17没有休息一小时,加上中午5小时耐力赛. 心里很清楚.是第一个问题的时候,几乎被解读为寻求最大的领域和.然后找到一个水体,快速A降. ...
随机推荐
- MyEclipse定位class文件
upolfind.bat :: 读取参数 例子 E:\workspaces\common-ws\xm_upol\WebRoot\WEB-INF\classes\${java_type_name} se ...
- LeetCode()Minimum Window Substring 超时,但觉得很清晰。
我的超时思路,感觉自己上了一个新的台阶,虽然超时了,但起码是给出了一个方法. 遍历s 一遍即可,两个指针,当找到了一个合格的字串后,start 开始走,直到遇到s[start]在t中 如果不符合,en ...
- 编译llvm+clang
第一步,下载llvm代码: git clone git@github.com:llvm-mirror/llvm.git 第二步,进入llvm/tools目录并下载clang代码 cd llvm/too ...
- 渴切API参考手册
渴切:是国内优秀的开源css框架. 渴切是一个开源中文 (X)HTML/CSS 框架 ,它的目的是减少你的css开发时间.它提供一个可靠的css基础去创建你的项目,能够用于网站的快速设计,通过重设和重 ...
- IplImage 结构解读(转)
typedef struct _IplImage { int nSize; /* IplImage大小 */ int ID; ...
- java之框架
框架有哪些?C++语言的QT.MFC.gtk,Java语言的SSH,php语言的 smarty(MVC模式),python语言的django(MTV模式)等等设计模式有哪些?工厂模式.适配器模式.策略 ...
- windowDialog销毁页面的问题
[结贴] windowDialog销毁页面的问题 [复制链接] Ghost丶 15 主题 91 帖子 200 积分 中级会员 积分 200 发消息 1# 电梯直达 发表于 2015-8- ...
- 虚拟机Ubuntu16,caffe环境搭建
虚拟机下的Ubuntu16.04+caffe+onlycup 官网的step很重要,要跟着官网,的步骤来:http://caffe.berkeleyvision.org/installation.ht ...
- Linux批量更改文件后缀名
一.rename解决 1. Ubuntu系统下 rename 's/\.c/\.h/' ./* 把当前目录下的后缀名为.c的文件更改为.h的文件 2. CentOS5.5系统下 rename . ...
- 【知识点】安全存储服务(SSS)目标应用程序类型
存在若干种类型的目标应用程序.它们分为两大类:单独的目标应用程序和组目标应用程序.目标应用程序的类型与用于映射用户凭据的帐户类型对应.如果每个用户都在目标应用程序中具有一个帐户,则选择单独的类型.如果 ...