集训第一周总结

这总结也算是迟到了吧,第二周都快过完了才写……
集训的第一周首先是重做市选的题目。
首先是先重做了上午的题。在这里先简单说说思路:
  第一题主要是用贪心策略,计算出最多能举行的比赛,再通过枚举计算举行x场比赛是否成立,求出最大值。
  第二题就是通过偏移量求出公式,(具体证明当然是另外开一篇来讲啦):求每一个节点在k叉树上的父亲的公式——(x + k - 2) / k。接着不停地将两个节点变成自己的父亲,直到两个节点相同为止。
  第三题用到的是一种组合的方法,用杨辉三角求出组合数,接着把数串排序,求出组合中每一个数出现的次数,求和得到答案。
  第四题通过哈希原字符串后求最长上升序列,得到答案。
其次是做下午的题,到现在后两题虽然思路懂了,可就是做不出来
前两题比较简单:
第一题就是计算每一个百分比四舍五入前可能的最大值和最小值,看100%在不在其中。要注意的就是%0不能再四舍了←_←因为这个在考试时只有9分 ←_←
第二题计算每一次的偏移量,把可能的k都列入数组,求出可能性最大的k,以及无论k为多少在正确的序列中都能得到与第一个相同而且现在也相同的个数,最后求出他们的和即可。
第三和第四题就算了吧……编都编不出,讲肯定也讲不好……
然后做的就是USACO OPEN的题
USACO的题有一个特点,就是分组,而且在不同的组中会出现相似的题,只不过难度更大而已……
铜牌组有一题,叫bcs,做得困难至极:模拟或者枚举的难度十分高,高得可以和铂金相比(当然不可能,铂金还有升级版的……)
第一题就是纯粹的枚举,枚举起始点,计算增加k之后有多少个钻石的美观值在这个区间中,直接取最大值就好
第二题,就是bcs了,难得程序都有快100行了……有两种办法,只是其中一种到现在还不知道哪里错了,明明思路是对的……就是枚举哪两块碎片,怎样拼可以拼成要求的那个样子。
第三题就是枚举卖掉哪一头牛,计算当前的最大的x,最小的x,最大的y,最小的y,直接求出面积,不过按这样做会超时……要预处理,输入时计算最大的和第二大的x,y,最小的和第二小的x,y,判断卖掉的奶牛是不是这四个角钟的一个,如果是就换成第二的那个。直接计算出面积。

银牌组的第一题也是卖奶牛那个,只不过卖了三头:
首先预处理最大的值和最小的值分别会是谁,求出前4的可疑人选,枚举可能会删掉的牛,计算面积。虽然有点慢,但也比铜牌的硬做快一些,省去了一些亢余操作。
第二题也是那个钻石的题,只是展示架多了一个。预处理出从左开始,每一个数字为起点计算有多少个处于这个距离当中,直接用单调就好,从另一边再开始求,最后让它们单调化,如果有一个区间的个数没有自己多,就拆了它……
最后直接计算这样会有多少个钻石,这样计算是不会让钻石重复的,具体证明会另开一篇来讲。
第三题就是逆向思考,先开一个,看是不是连通的,这样自然就能用并查集暴力做,然后就过了……
金牌组另开几篇来讲,铂金也是(虽然没几题会做……)。
至于第一周后面的两次模拟,同样会专门开两篇来讲。
以下就是我的代码

市选am 1

#include <cstdio>
#include <iostream>

int get_ans(int e,int em,int m,int mh,int h)
{
for(int i = e + em;i >= 0;i--)
{
if( e + em < i || mh + h < i) continue;

int E,M,H;

E = std :: min ( e + em - i, em );
H = std :: min ( h + mh - i, mh );

M = m + E + H;

if( M >= i ) return i;
}
}

int main()
{
freopen("pro.in","r",stdin);
freopen("pro.out","w",stdout);

int R;
scanf("%d",&R);
for(int r = 0;r < R;r++)
{
int e,em,m,mh,h;
scanf("%d%d%d%d%d",&e,&em,&m,&mh,&h);

printf("%d\n", get_ans(e,em,m,mh,h) );
}

return 0;
}

市选am2

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>

typedef long long llint;

llint n;
int k;

llint get_ans(llint a,llint b)
{
if(k == 1) return std :: abs(a-b);

llint ans=0;
while (a != b)
{
if(a < b) std :: swap(a,b);

a = (a - 2 + k) / k;
ans ++ ;
}

return ans;
}

int main()
{
freopen("ktree.in","r",stdin);
freopen("ktree.out","w",stdout);

int q;
scanf("%I64d%d%d",&n,&k,&q);
for(int Q = 0;Q < q;Q++)
{
llint a,b;

scanf("%I64d%I64d",&a,&b);

printf("%I64d\n", get_ans(a,b) );
}
return 0;
}

市选am3

#include <cstdio>
#include <algorithm>

const int MOD = (1e9) + 7,
MAXN = 1 << 17 ,
MAXK = 55;

typedef long long llint;

llint C[MAXN][MAXK];
int a[MAXN];
int n,k;

int main()
{
freopen("summax.in","r",stdin);
freopen("summax.out","w",stdout);

scanf("%d%d",&n,&k);

C[0][0]=1;
for(int i = 1;i <= n;i++)
for(int j = 0;j < k;j++)
{
C[i][j] = C[i-1][j];

if(j > 0) C[i][j] += C[i-1][j-1];
C[i][j] %= MOD;
}

for(int i = 0;i < n;i++)
{
scanf("%d",&a[i]);
}

std :: sort(a,a+n);

llint ans = 0;
for(int i = 0;i < n;i++)
{
ans += (a[i] * C[i][k-1] % MOD) % MOD;
ans %= MOD;
}

printf("%I64d\n",ans);
return 0;
}


市选am4

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <string>
#include <cctype>

#define string std :: string

const int MAXN = (1e6) * 2 + 10 ,
MOD = (1e7) + 7;

inline int get_c(const char ch) { return ch - 'A' + 1; }

int n;
string st;
int S[MAXN];
int s[MOD];
int ans;

inline void get_str(string& st){
st.clear();
char ch;
ch = getchar();

while ( !isalpha(ch) ) ch = getchar();
while ( isalpha(ch) ){
st.push_back(ch);
ch = getchar();
}
}

void get_hash(const string st){
int Lh,Rh;
Lh = Rh = 0;

const int len = st . size();
int now_ans = 0;
for(int i = 0,j = len-1;i < len;++i,--j)
{
Lh *= 28; Lh += get_c(st[i]);
Lh %= MOD;

int tmp = get_c(st[j]);
tmp *= S[i];
tmp %= MOD;

Rh += tmp;
Rh %= MOD;

if(Lh == Rh)
{
now_ans = std :: max(now_ans,s[Lh]+1);
}
}
s[Lh] = std :: max(now_ans,s[Lh]);
ans = std :: max(now_ans, ans);
}

int main(){
freopen("psfix.in","r",stdin);
freopen("psfix.out","w",stdout);

scanf("%d\n",&n);

S[0] = 1;
for(int i = 1;i < MAXN;i++){
S[i] = S[i-1] * 28;
S[i] %= MOD;
}

for(int i = 0;i < n;i++){
get_str(st);
get_hash(st);
}

printf("%d\n",ans);
return 0;
}

市选pm1

#include <cstdio>

int main()
{
freopen("ele.in","r",stdin);
freopen("ele.out","w",stdout);

int r;
scanf("%d",&r);
for(int R = 0;R < r;R++)
{
int n;
int low = 0,up = 0;
scanf("%d",&n);

for(int i = 0;i < n;i++)
{
int x;
scanf("%d",&x);
x *= 100;

if (x != 0) low += x - 50;
up += x + 49;
}

if( low <= (1e4) && (1e4) <= up ) printf("NO\n");
else printf("YES\n");
}
return 0;
}


市选pm2

#include <cstdio>
#include <algorithm>

const int MAXN = (1e6) + 5;

int cnt,n;
int a[MAXN];
int k[MAXN];

int get_k();

int main(){
freopen("code.in","r",stdin);
freopen("code.out","w",stdout);

scanf("%d",&n);
for(int i = 0;i < n;i++){
scanf("%d",&a[i]);
}

int x=0,ans=1;
for(int i = 1;i < n;i++)
{
if(a[i] > a[i-1]) x++;
if(a[i] < a[i-1]) x--;

if(a[i] == a[0] && x == 0) ans++;
else{
if( x != 0 && ! ((a[i]-a[0]) % x) ){
k[cnt++] = (a[i]-a[0]) / x;
}
}
}

std :: sort(k,k+cnt);

printf("%d\n",get_k() + ans);

return 0;
}

int get_k(){
int last = k[0] , ans = 0 , count = 0;
for(int i = 0;i < cnt;i++)
{
if(last == k[i]) count ++;
else{
ans = std :: max(ans,count);
count = 1;
last = k[i];
}
}

return std :: max(ans , count);
}

Open Bronze1

#include <cstdio>
#include <cstring>

int main(){
freopen("diamond.in","r",stdin);
freopen("diamond.out","w",stdout);

int n,k;
scanf("%d%d",&n,&k);
int a[n];
memset(a,0,sizeof a);

for(int i = 0;i < n;i++) scanf("%d",&a[i]);

int ans = 0;
for(int i = 0;i < n;i++){
int cnt = 0;

for(int j = 0;j < n;j++){
if(a[j] >= a[i] && a[j] <= a[i] + k){
cnt++;
}
}

if(cnt > ans){
ans = cnt;
}
}

printf("%d\n",ans);
return 0;
}


别问我Bronze2哪去了←_←
Open Bronze3

#include <cstdio>

const int MAXN = (1e4) * 5 + 5 ,
INF = 0x7fffffff;

int n;
int x[MAXN],y[MAXN];
int MaxX1,MaxX2;
int MinX1 = INF , MinX2 = INF;

int MaxY1,MaxY2;
int MinY1 = INF , MinY2 = INF;

int main() {
freopen("reduce.in","r",stdin);
freopen("reduce.out","w",stdout);

scanf("%d",&n);
for(int i = 0;i < n;i++){
scanf("%d %d",&x[i],&y[i]);

if(x[i] < MinX1) MinX2 = MinX1 , MinX1 = x[i];
else if(x[i] < MinX2) MinX2 = x[i];

if(y[i] < MinY1) MinY2 = MinY1 , MinY1 = y[i];
else if(y[i] < MinY2) MinY2 = y[i];

if(x[i] > MaxX1) MaxX2 = MaxX1 , MaxX1 = x[i];
else if(x[i] > MaxX2) MaxX2 = x[i];

if(y[i] > MaxY1) MaxY2 = MaxY1 , MaxY1 = y[i];
else if(y[i] > MaxY2) MaxY2 = y[i];
}

int ans = (MaxX1-MinX1) * (MaxY1-MinY1);
for(int i = 0;i < n;i++){
int xMin = (x[i] == MinX1 ? MinX2 : MinX1);
int xMax = (x[i] == MaxX1 ? MaxX2 : MaxX1);

int yMin = (y[i] == MinY1 ? MinY2 : MinY1);
int yMax = (y[i] == MaxY1 ? MaxY2 : MaxY1);

if(ans > (xMax - xMin) * (yMax - yMin)) ans = (xMax - xMin) * (yMax - yMin);
}

//printf("Minx:%d %d Miny:%d %d Maxx%d %d Maxy%d %d\n",MinX1,MinX2,MinY1,MinY2,MaxX1,MaxX2,MaxY1,MaxY2);
printf("%d\n",ans);

return 0;
}


Open Silver1

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>

const int MAXN = 50050 ,
INF = 0x7fffffff;

int n;
bool visited[MAXN];
int s[MAXN];
int x[MAXN],y[MAXN];

struct Tnode {
int value , num;
Tnode() {
value = num = 0;
}

Tnode(int x,int y) {
value = x;
num = y;
}
}a[MAXN],b[MAXN];

bool _cmp(Tnode a,Tnode b) {
return a.value < b.value || a.value == b.value && a.num < b.num;
}

int get_area(int u,int v,int w) {
int xMax = -INF,xMin = INF , yMax = -INF,yMin = INF;
for(int i = 0;i < n;i++) {
if(i == u || i == v || i == w) continue;

xMax = std :: max(xMax,x[i]);
xMin = std :: min(xMin,x[i]);
yMax = std :: max(yMax,y[i]);
yMin = std :: min(yMin,y[i]);
}

return (xMax - xMin) * (yMax - yMin);
}
/*
int change(int v,int u,int w)
{
int a=-oo,b=oo,c=-oo,d=oo;
for (int i=0; i<n; i++)
if (i!=v && i!=u && i!=w)
{
if (x[i]>a) a=x[i];
if (x[i]<b) b=x[i];
if (y[i]>c) c=y[i];
if (y[i]<d) d=y[i];
}
return (a-b)*(c-d);
}
*/

int main() {
freopen("reduce.in","r",stdin);
freopen("reduce.out","w",stdout);

scanf("%d",&n);
for(int i = 0;i < n;i++) {
scanf("%d%d",&x[i],&y[i]);

a[i] = Tnode(x[i],i);
b[i] = Tnode(y[i],i);
}

std :: sort( a , a+n ,_cmp );
std :: sort( b , b+n ,_cmp );

int ans = INF;
int cnt = 0;

for(int i = 0;i < 3;i++) {
if(!visited[a[i].num]) {
++cnt;
s[cnt] = a[i].num;
visited[ s[cnt] ] = true;
}

if(!visited[b[i].num]) {
++cnt;
s[cnt] = b[i].num;
visited[ s[cnt] ] = false;
}
}

for(int i = 3; a[i].num == a[i-1].num ; i++) {
if(!visited[a[i].num]) {
++cnt;
s[cnt] = a[i].num;
visited[ s[cnt] ] = true;
}
}

for(int i = 3;b[i].num == b[i-1].num;i++) {
if(!visited[b[i].num]) {
++cnt;
s[cnt] = b[i].num;
visited[ s[cnt] ] = false;
}
}

for(int i = n-1;i > n-4;i--) {
if( !visited[a[i].num] ) {
++cnt;
s[cnt] = a[i].num;
visited[ s[cnt] ] = true;
}

if(!visited[b[i].num]) {
++cnt;
s[cnt] = b[i].num;
visited[ s[cnt] ] = false;
}
}

for(int i = n-4; a[i].num == a[i-1].num ; i--) {
if(!visited[a[i].num]) {
++cnt;
s[cnt] = a[i].num;
visited[ s[cnt] ] = true;
}
}

for(int i = 3;b[i].num == b[i-1].num;i--) {
if(!visited[b[i].num]) {
++cnt;
s[cnt] = b[i].num;
visited[ s[cnt] ] = false;
}
}

for(int i = 1;i < cnt-1;i++) {
for(int j = i+1;j < cnt;j++) {
for(int k = j+1;k <= cnt;k++) {
ans = std :: min(ans , get_area(s[i],s[j],s[k]));
}
}
}

printf("%d\n",ans);
return 0;
}


Open Silver2

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>

const int MAXN = (1e5) + 5;

int n,k;
int a[MAXN];
int Left[MAXN],Right[MAXN];

int main() {
freopen("diamond.in","r",stdin);
freopen("diamond.out","w",stdout);

scanf("%d%d",&n,&k);
for(int i = 1;i <= n;i++) {
scanf("%d",a+i);
}

std :: sort(a+1,a+n+1);

int j = 1;
for(int i = 1;i <= n;i++) {
while (j <= n && a[j] - a[i] <= k) j++;
j--;
Left[i] = j-i+1;
}

j = n;
for(int i = n;i > 0;i--) {
while (j > 0 && a[i] - a[j] <= k) j--;
j++;
Right[i] = i-j+1;
}

for(int i = n;i > 0;i--) Left[i] = std :: max(Left[i+1] , Left[i]);
for(int i = 1;i <= n;i++) Right[i] = std :: max(Right[i-1] , Right[i]);

int ans = 0;
for(int i = 1;i <= n;i++) ans = std :: max(ans,Right[i-1] + Left[i]);

printf("%d\n",ans);

return 0;
}


Open Silver3

#include <cstdio>

const int MAXN = 3005;

int fa[MAXN];
bool ans[MAXN],F[MAXN] = {0};
int a[MAXN];
int n,m;
bool edge[MAXN][MAXN];

int _find(int root) {
if( fa[root] == root ) return root;
return fa[root] = _find( fa[root] );
}

int main() {
freopen("closing.in","r",stdin);
freopen("closing.out","w",stdout);

scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++) fa[i] = i;

for(int i = 0;i < m;i++) {
int u,v;
scanf("%d%d",&u,&v);
edge[u][v] = edge[v][u] = 1;
}

for(int i = n-1;i >= 0;i--) {
scanf("%d",&a[i]);
}

for(int i = 0;i < n;i++) {
bool f = 1;
F[ a[i] ] = 1;

int fa1;
for(int j = 1;j <= n;j++) {
fa1 = _find(a[i]);
if( j == a[i] || !edge[ a[i] ][j] || !F[j]) continue;

int fa2 = _find(j);
if(fa1 != fa2) {
fa[fa2] = fa1;
}
}

for(int j = 1;j <= n;j++) {
fa1 = _find(a[i]);
int fa2 = _find(j);

if(F[j] && fa1 != fa2) f=0;
}

ans[i] = f;


for(int i = 1;i <= n;i++) printf("%d ",fa[i]);
puts("");

}

for(int i = n-1;i >= 0;i--) {
printf("%s\n",ans[i] ? "YES" : "NO");
}
return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值