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降. ...
随机推荐
- Android——数据存储(课堂代码整理:SharedPreferences存储和手机内部文件存储)
layout文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:an ...
- R中的统计检验函数
正态性W检验 shapiro.test()用Shapiro-Wilk W统计量做数据的正态性检验. 经验分布的Kolmogorov-Smirnov检验 ks.test()Kolmogorov-Smir ...
- 【转载】C/C++中#ifdef和#endif的用法
转于 http://www.cnblogs.com/renyuan/archive/2013/05/22/3092362.html 今天笔试的时候遇到这个问题,整理一下! 一般情况下,源程序中所有的行 ...
- RabbitMQ 安装
Install Erlang from the Erlang Solutions repository or Follow the instructions under "Installat ...
- [DFNews] GetData也出取证软件了
从事计算机取证的应该都听说过MIP(Mount Image Pro).VFC仿真和Recover My Files,上述三个应用比较广泛的软件都是GetData公司的产品.GetData现在也推出了自 ...
- (Array)27. Remove Element
Given an array and a value, remove all instances of that value in place and return the new length. D ...
- Chap5:32– 34
32. 从 1 到 n 整数中 k (0,1, 2, 3, 4, 5, 6, 7, 8, 9)出现的次数. 时间 O(log10N) A. 当 K != 0 时: 以 n = 2014,K = 1 ...
- 31. Flatten Binary Tree to Linked List
Flatten Binary Tree to Linked List Given a binary tree, flatten it to a linked list in-place. For ex ...
- .NET使用一般处理程序生成验证码
运行的效果图: HTML的代码: <head> <script type="text/javascript"> function changeCode() ...
- jdbc操作数据库
JDBC全称为:Java DataBase Connectivity(java数据库连接). SUN公司为了简化.统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC. 学习JD ...