这场比赛特点在于两个简单题太坑,严重影响了心情。。导致最后只做出两题....当然也反映出心理素质的重要性

1002:

题意:一个矩阵b[n][n]通过数组 a[n]由以下规则构成,现在已知b[n][n]问是否有对应的数组a[n]

解法:

首先都是位运算所以不同位是不会互相影响的,即可按位考虑。

又发现,只要知道a[0]就可以算出通过b[0][]算出所有的a[],这样可以假设a[0]为0或1,由b[0][]得到一个完整的数组a[],再check这个数组a是否能正确的得到其他的b[][]即可

时间复杂度约为32*2*n^2 对于n=1000是可以接受的

当然队友是用2-SAT做的 吊吊吊吊吊orz 我就没写了,这里贴上队友的代码

代码:

#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include <stdio.h>
using namespace std; const int maxn = ; struct TwoSAT
{
int n;
vector<int> G[maxn * ];
bool mark[maxn * ];
int S[maxn * ], c; bool dfs(int x)
{
if(mark[x ^ ]) return false;
if(mark[x]) return true;
mark[x] = true;
S[c++] = x;
for(int i = ; i < G[x].size(); i++)
if(!dfs(G[x][i])) return false;
return true;
} void init(int n) // 一定要注意初始化的点数,别弄错
{
this->n = n;
for(int i = ; i < n * ; i++) G[i].clear();
memset(mark, , sizeof(mark));
} // x = xval or y = yval
void add_clause(int x, int xval, int y, int yval) // 编号从0~n-1
{
x = x * + xval;
y = y * + yval;
G[x ^ ].push_back(y);
G[y ^ ].push_back(x);
} // 当x==xval 时可推导出 y==yval
void add_edge(int x, int xval, int y, int yval)
{
x = x * + xval;
y = y * + yval;
G[x].push_back(y);
} bool solve()
{
for(int i = ; i < n * ; i += )
if(!mark[i] && !mark[i + ])
{
c = ;
if(!dfs(i))
{
while(c > ) mark[S[--c]] = false;
if(!dfs(i + )) return false;
}
}
return true;
}
}; TwoSAT solver;
int n;
int a[maxn][maxn]; bool check(int l)
{
solver.init(n);
for(int i = ; i < n; i++)
for(int j = ; j < n; j++)
{
int bit = (a[i][j] & ( << l))>>l; if(i == j)
{
if(a[i][j] != )
{
return false;
}
}
else if(a[i][j] != a[j][i])
{
return false;
}
else if(i % == && j % == ) // &
{
solver.add_edge(i, , j, bit);
solver.add_edge(j, , i, bit);
if(bit)
{
solver.add_edge(i, , i, );
solver.add_edge(j, , j, );
}
}
else if(i % == && j % == ) // |
{
solver.add_edge(i, , j, bit);
solver.add_edge(j, , i, bit);
if(!bit)
{
solver.add_edge(i, , i, );
solver.add_edge(j, , j, );
}
}
else // ^
{
solver.add_edge(i, , j, bit ^ );
solver.add_edge(j, , i, bit ^ );
solver.add_edge(i, , j, bit);
solver.add_edge(j, , i, bit);
}
}
return solver.solve();
} int main()
{ while(~scanf("%d", &n))
{
for(int i = ; i < n; i++)
for(int j = ; j < n; j++)
{
scanf("%d", &a[i][j]);
}
bool flag = true;
// 枚举每一位,l为座椅的 位数
for(int l = ; l <= ; l++)
{
if(!check(l))
{
flag = false;
break;
}
}
puts(flag?"YES":"NO");
} return ;
}

1003:

题意:

这个简单题题意挺恶心的。。先开始一直没读懂。。

小明要在五座山上采五堆蘑菇,每堆的个数是0~2012,采完后必须送出三堆和为1024倍数的蘑菇(否则全送出),回家之前如果总数大于1024还要一直被抢1024。

现在已经采了n堆(n<=5),剩下的可以任意采(0~2012)问最终最多能拿回家多少蘑菇.

解法:

分情况特判.....以下省略好多字

代码:

#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const double eps = 1e-;
int a[];
const int mod = ;
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int n;
while (~scanf ("%d", &n))
{
memset(a, , sizeof(a));
int sum = ;
for (int i = ; i < n; i++)
{
scanf ("%d", a+i);
sum += a[i];
}
int ans = , res = ;
if (n<=)
{
printf("%d\n", );
continue;
}
if (n == )
{
int ans = ;
bool flag = ;
for (int i = ; i < ; i++)
{
for (int j = i+; j < ; j++)
{
int tmp = a[i]+a[j];
if (tmp)
ans = max(ans, (tmp%) ? (tmp%) : );
for (int k = j +; k < ; k++)
{
if ((a[i] + a[j] + a[k]) % == )
flag = ;
}
}
}
if (flag)
printf("%d\n" , );
else
printf("%d\n" ,ans);
continue;
}
if (n == )
{
bool f = ;
int ans = ;
for (int i = ; i < ; i++)
{
for (int j = i+; j < ; j++)
{
for (int k = j+; k < ; k++)
{
int tmp = a[i] +a[j] +a[k];
if (tmp % == )
{
if (sum-tmp)
ans = max(ans, ((sum-tmp)%) ? (sum-tmp)% : );
}
}
}
}
printf("%d\n",(ans > ) ? (ans %) : ans);
}
}
return ;
}

1004:

题意:

 求y的取值范围

思路:

高中数学题,移项得到一个二次函数,然后各种分类讨论,太麻烦了没敢写。。。

1005:

题意:

一颗给定的无根树里面有边权,要求选定一个根使得此根到所有节点的代价最大,代价定义为路径上边权的最小值

解法:

奇怪的贪心,先按边权大到小排序,然后加边,并查集维护,每次合并的时候贪心的取代价最小(还是不知道为什么是对的)

代码:

 #include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const double eps = 1e-;
const int maxn = 2e5+;
int pa[maxn],rnk[maxn];
struct Edge
{
int frm, to, cst;
bool operator < (const Edge &rhs)const
{
return cst > rhs.cst;
}
}e[maxn];
int find (int x)
{
return pa[x] = (pa[x] == x ? x : find(pa[x]));
}
ll ans[maxn];
void Merge(int x, int y, int cost)
{
int fx = find(x);
int fy = find(y);
if (rnk[fx] < rnk[fy])
swap(fx, fy);
ans[fx] = max(ans[fy]+(ll)rnk[fx]*cost, ans[fx]+(ll)rnk[fy]*cost);
pa[fy] = fx;
rnk[fx] += rnk[fy];
}
void init ()
{
memset(ans, , sizeof(ans));
for (int i = ; i < maxn; i++)
{
pa[i] = i;
rnk[i] = ;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int n;
while (~scanf ("%d", &n))
{
int u, v, c;
init();
for (int i = ; i < n-; i++)
{
scanf ("%d%d%d", &u, &v, &c);
e[i].frm = u, e[i].to = v, e[i].cst = c;
}
sort (e,e+n-);
for (int i = ; i < n-; i++)
{
Merge(e[i].frm, e[i].to, e[i].cst);
}
printf("%I64d\n", ans[find()]);
}
return ;
}

1008:

题意:

知道n个数的和sum,以及n个数的LCM,求合法的组成方案(排列)

解法:
发现lcm的转移只可能通过lcm的约数,(一开始和分解质因数搞呢,后来经过学长提醒发现直接找出约数即可 orz),约数数量不是很多。。这样就可以dp了

把约数哈希一下 dp[i][j][k]代表考虑到第i个数,当前lcm为总LCM的第j个约数,当前sum为k的方案数,转移很容易

代码:

#include <iostream>
#include <stdio.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<ctype.h>
using namespace std;
#define MAXN 10000
const int mod=1e9+;
bool is(int p)
{
for(int i=; i*i<=p; i++)
{
if(p%i==)
return ;
}
return ;
}
int gcd(int a,int b)
{
return b==?a:gcd(b,a%b);
}
int lcm(int a,int b)
{
return a/gcd(a,b)*b;
}
int prime[];
int s[];
int dp[][][];
int a[];
int ha[];
int l[][];
int sum,L,n,m;
int main()
{
// freopen("in.txt","r",stdin);
m=;
for(int i=; i<=; i++)
{
if(is(i))
{
prime[m++]=i;
}
}
while(scanf("%d%d%d",&sum,&L,&n)!=EOF)
{
memset(ha,-,sizeof(ha));
int lim=;
for(int i=;i<=L;i++)
{
if(L%i==)
{
ha[L/i]=lim;
s[lim++]=L/i;
}
}
for(int i=;i<lim;i++)
{
for(int j=;j<lim;j++)
{
l[i][j]=lcm(s[i],s[j]);
}
}
memset(dp,,sizeof(dp));
dp[][][lim-]=;
for(int i=;i<=n;i++)
{
for(int j=;j<=sum;j++)
{
for(int k=;k<lim;k++)
{
if(!dp[i-][j][k])
continue;
for(int t=;t<lim;t++)
{
if(j+s[t]<=sum)
{
if(ha[l[k][t]]==-)
continue;
dp[i][j+s[t]][ha[l[k][t]]]+=dp[i-][j][k];
dp[i][j+s[t]][ha[l[k][t]]]%=mod;
}
}
}
}
}
cout<<dp[n][sum][]<<endl;
}
return ;
}

1010:

题意:
一个大矩形被一些线段分成了小矩形,现在给定两个点的坐标,求出删除一些线段使这两点在同一矩形后剩余矩形数量的最大值。

思路:

其实就是要找所求两点共同所在的最小的矩形(除此之外的线段都不删除,得到的剩余矩形数肯定最多)。

而按照题意的分割矩形法其实就是形成了一颗树,这样就发现两个点所在的最小矩形其实是这两个点当前所在矩形的lca

理论ac了。。代码还没写

1011:

题意:

给定一个等比数列 1(或者0)+k+k^2+....k^r的和 S,要求求出r 和k,多解首先满足r*k最小,然后满足 r最小

解法:

由于k>=2所以可以计算发现r最大为40,则可以枚举r,二分求得k ,如果r和二分出的k刚好等于 k或者k-1 则符合题意,可以统计答案

坑点是二分过程中容易溢出

代码:

#include <iostream>
#include <stdio.h>
using namespace std;
typedef long long ll; ll n; ll equ(ll ak , int r)
{
ll ans = ;
ll k = ak;
for(int i = ; i <= r; i++)
{
ans += k;
if(ans > n + )
break;
if(ans<=)
return 10000000000000LL;
k *= ak;
}
return ans;
} int main()
{ while(~scanf("%I64d", &n))
{
ll ansk = 10000000000000LL;
int ansr = ; // 枚举r
for(int r = ; r <= ; r++)
{
// 二分k
ll l = , R = 1000000000001LL;
while(l < R)
{
ll m = (l + R + ) / ;
if(equ(m, r) <= n)
{
l = m;
}
else
{
R = m - ;
}
} ll k = l;
if(equ(k, r) == n)
{
// 保存答案
if((ansk * ansr > k * r) || ((ansk * ansr == k * r) && ansr > r))
{
ansk = k;
ansr = r;
}
} // 二分k
l = , R = 1000000000001LL;
while(l < R)
{
ll m = (l + R + ) / ;
if(equ(m, r) <= n + )
{
l = m;
}
else
{
R = m - ;
}
} k = l;
if(equ(l, r) == n + )
{
// 保存答案
if((ansk * ansr > k * r) || ((ansk * ansr == k * r) && ansr > r))
{
ansk = k;
ansr = r;
}
}
}
printf("%d %I64d\n", ansr, ansk);
} return ;
}

【2012长春区域赛】部分题解 hdu4420—4430的更多相关文章

  1. 2015年ACM长春区域赛比赛感悟

    距离长春区域赛结束已经4天了,是时候整理一下这次比赛的点点滴滴了. 也是在比赛前一周才得到通知要我参加长春区域赛,当时也是既兴奋又感到有很大的压力,毕竟我的第一场比赛就是区域赛水平,还是很有挑战性的. ...

  2. 【2012天津区域赛】部分题解 hdu4431—4441

    1001: 题意:给你13张麻将牌,问可以胡哪些张 思路: 枚举可能接到的牌,然后dfs判断能否胡 1002: 题意: 已知n,m 求 n的所有约数在m进制下的平方和 做法:队长用java高精度写的 ...

  3. HDU 5527 Too Rich ( 15长春区域赛 A 、可贪心的凑硬币问题 )

    题目链接 题意 : 给出一些固定面值的硬币的数量.再给你一个总金额.问你最多能用多少硬币来刚好凑够这个金额.硬币数量和总金额都很大   分析 : 长春赛区的金牌题目 一开始认为除了做类似背包DP那样子 ...

  4. HDU 4818 RP problem (高斯消元, 2013年长春区域赛F题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4818 深深地补一个坑~~~ 现场赛坑在这题了,TAT.... 今天把代码改了下,过掉了,TAT 很明显 ...

  5. 2018-2019 ACM-ICPC 徐州区域赛 部分题解

    题目链接:2018-2019 ACM-ICPC, Asia Xuzhou Regional Contest A. Rikka with Minimum Spanning Trees 题意: 给出一个随 ...

  6. Travel(HDU 5441 2015长春区域赛 带权并查集)

    Travel Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Su ...

  7. hdu 4463 有一条边必须加上 (2012杭州区域赛K题)

    耐克店 和 苹果店必须相连 Sample Input42 30 01 00 -1 1 -10 Sample Output3.41 # include <iostream> # includ ...

  8. ACM学习历程——HDU4472 Count(数学递推) (12年长春区域赛)

    Description Prof. Tigris is the head of an archaeological team who is currently in charge of an exca ...

  9. ICPC2019上海区域赛 部分题解(正在更新)

    K. Color Graph 题意: 给定一个简单图,点个数<=16,删去部分边后,使得该图中无边数为奇数得环,问剩下的边数最大为多少? 思路: 如果一个图中无奇数边的环,那么这个图一定是个二分 ...

随机推荐

  1. [Angular 2] Passing Template Input Values to Reducers

    Angular 2 allows you to pass values from inputs simply by referencing them in the template and passi ...

  2. shell 脚本实现的守护进程

    转自:http://blog.csdn.net/cybertan/article/details/3235722 转自:http://blog.sina.com.cn/s/blog_4c451e0e0 ...

  3. hdu3368之DFS

    Reversi Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Su ...

  4. 使用Intent实现Activity的显式跳转

    [正文] 这里以按钮实现活动跳转为例,为实现这个功能,我们需要三个步骤: 1.点击按钮才发生页面跳转,因此,第一步我们先要找到要点击的按钮 如何拿到按钮对象呢?通过资源id,前面我们提到过,在R.id ...

  5. 通知中心 NSNotificationCenter

    NSNotificationCenter 通知中心提供了一种在程序内广播信息的途径,一个NSNotificationCenter对象本质上是一个通知分发表(notification dispatch ...

  6. canvas toDataUrl 跨域问题

    使用canvas 的 toDataUrl方法会遇到跨域问题 chrome 会报下面的错误: Uncaught SecurityError: Failed to execute 'toDataURL' ...

  7. AngularJs学习之ng-repeat

    ng-repeat用来遍历一个集合或为集合中的每个元素生成一个模板实例.集合中的每个元素都会被赋予自己的模板和作用域.同时每个模板实例的作用域中都会暴露一些特殊的属性. $index:遍历的进度(0 ...

  8. 【※索引】mysql索引常用命令

    索引分单列索引和组合索引.单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引.组合索引,即一个索包含多个列. MySQL索引类型包括: (1)普通索引 这是最基本的索引,它没 ...

  9. An attempt to attach an auto-named database for file

    在用VS自带的 .mdf读取(joint)时,报错: Server Error in '/' Application. An attempt to attach an auto-named datab ...

  10. hadoop2.4.1伪分布式搭建

    1.准备Linux环境 1.0点击VMware快捷方式,右键打开文件所在位置 -> 双击vmnetcfg.exe -> VMnet1 host-only ->修改subnet ip ...