TCO2016乱做
来源:互联网 发布:泯然众人 知乎 编辑:程序博客网 时间:2024/05/22 16:16
目录
模拟&搜索
1A 250pts
1B 250pts
1C 250pts
2A 400pts
贪心
1B 500pts
1C 500pts
三分
1B 1000pts
动态规划
1A 500pts
数学相关
Regional Wildcard 250pts
题目
Round 1A
250pts
题意简述
给你一个形如HH:MM的时刻,问把时针分针倒换之后的时刻是多少。
数据范围
保证时针分针指向的是表盘的数字。
思路
直接模拟即可
代码
#include<cstdio>#include<string>#include<iostream>using namespace std;class EllysTimeMachine{ public: int h,m,hh,mm; string getTime(string t) { h=(t[0]-'0')*10+(t[1]-'0'); m=(t[3]-'0')*10+(t[4]-'0'); hh=(m/5+11)%12+1; mm=h*5%60; string ret; ret+=(hh/10)+'0'; ret+=(hh%10)+'0'; ret+=':'; ret+=(mm/10)+'0'; ret+=(mm%10)+'0'; return ret; }};
500pts
题意简述
有
数据范围
思路
DP。
先排序。
决策是是否和前一个配对。
这样复杂度是
我们可以对后面的
一开始想成了二分答案二分图匹配= =
代码
#include<cstdio>#include<cstring>#include<cstdlib>#include<vector>#include<algorithm>using namespace std;class EllysSocks{ public: int f[1010][1010]; int mn[1010][1010]; int n; int getDifference(vector<int> s,int p) { memset(f,0x3f,sizeof(f)); memset(mn,0x3f,sizeof(mn)); n=s.size(); sort(s.begin(),s.end()); for (int i=1;i<n;i++) { f[i][0]=mn[i][0]=0; for (int j=1;j<=min(p,(i+1)/2);j++) { f[i][j]=min(f[i][j],mn[i-1][j]); if (i-2>=1) f[i][j]=min(f[i][j],max(abs(s[i]-s[i-1]),mn[i-2][j-1])); else f[i][j]=min(f[i][j],abs(s[i]-s[i-1])); mn[i][j]=min(mn[i-1][j],f[i][j]); } } return f[n-1][p]; }};
Round 1B
250pts
题意简述
给出一个数
数据范围
思路
略微观察之后会发现经过几次变换之后,数字会在
爆搜即可。
代码
#include<cstdio>#include<cmath>#include<cstring>using namespace std;class ExploringNumbers{ public: bool vis[1010]; bool is_prime(int n) { if (n==1) return false; for (int i=2;i<=int(sqrt(n));i++) if (n%i==0) return false; return true; } int dfs(int x) { if (is_prime(x)) return 1; if (x<=729) { if (vis[x]) return -1; vis[x]=1; } int tmp=0; while (x>0) tmp+=(x%10)*(x%10),x/=10; tmp=dfs(tmp); if (tmp==-1) return -1; else return tmp+1; } int numberOfSteps(int n) { memset(vis,0,sizeof(vis)); return dfs(n); }}
500pts
题意简述
给出
数据范围
思路
贪心。
按位贪心,从最大的数字开始,每次选取尽量多的。
代码
#include<cstdio>#include<vector>using namespace std;class ReplacingDigit{ public: int getMaximumStockWorth(vector<int> s,vector<int> d) { int fac10[10],f[100][20]={0},num[20]={0},cnt[20]={0}; int n,sum=0,last; fac10[0]=1; for (int i=1;i<=6;i++) fac10[i]=fac10[i-1]*10; n=s.size(); for (int i=0;i<n;i++) { int tmp=s[i],di=0; while (tmp) f[di][tmp%10]++,tmp/=10,cnt[di]++,di++; } for (int i=0;i<9;i++) num[i+1]=d[i]; for (int i=9;i>=0;i--) { last=cnt[i]; for (int j=9;j>=0;j--) { if (last-f[i][j]<=0) { sum+=last*j*fac10[i]; break; } last-=f[i][j]; sum+=f[i][j]*j*fac10[i]; if (last-num[j]<=0) { sum+=last*j*fac10[i]; num[j]-=last; break; } last-=num[j]; sum+=num[j]*j*fac10[i]; num[j]=0; } } return sum; }};
1000pts
题意简述
给出
再给出
还有一个特殊产生器,花费
求满足所有限制
数据范围
给出种子,数据根据给出的生成方式生成。
思路
三分+贪心。
如果以特殊产生器的
我们可以三分这个
代码
#include<cstdlib>#include<vector>#include<cstring>#include<cstdio>using namespace std;class SettingShield{ public: struct interval{ int l,r; }L[100010]; int n,h,t; int seq[100010],p[100010],rightmax[100010],tag[100010]; long long calc(int x) { for (int i=0;i<n;i++) p[i]=max(0,seq[i]-x); long long sum=1LL*x*t; int used=0; for (int i=0;i<n;i++) { used-=tag[i]; tag[i]=0; p[i]=max(0,p[i]-used); sum+=p[i]; used+=p[i]; tag[rightmax[i]+1]+=p[i]; } return sum; } long long getOptimalCost(int _n,int _h,int _t,vector<int> val0,vector<int> a,vector<int> b,vector<int> m) { n=_n; h=_h; t=_t; int dist; seq[0]=val0[0]; for (int i=1;i<n;i++) seq[i]=(1LL*a[0]*seq[i-1]+b[0])%m[0]; L[0].l=val0[1]; L[0].r=val0[2]; for (int i=1;i<h;i++) { L[i].l=min(1LL*n-1,(1LL*a[1]*L[i-1].l+b[1])%m[1]); dist=L[i-1].r-L[i-1].l; L[i].r=min(1LL*n-1,L[i].l+(1LL*a[2]*dist+b[2])%m[2]); } memset(rightmax,0xff,sizeof(rightmax)); for (int i=0;i<h;i++) rightmax[L[i].l]=max(rightmax[L[i].l],L[i].r); for (int i=1;i<n;i++) if (rightmax[i-1]>=i) rightmax[i]=max(rightmax[i],rightmax[i-1]); int l=0,r=1e7+10; long long ans=1LL<<60; for (int i=0;i<n;i++) if (rightmax[i]==-1) l=max(l,seq[i]); while (l<=r) { int mid1=l+(r-l)/3; int mid2=l+(r-l)*2/3; long long tmp1=calc(mid1),tmp2=calc(mid2); if (tmp1>=tmp2) { l=mid1+1; ans=min(ans,tmp2); } else { r=mid2-1; ans=min(ans,tmp1); } } return ans; }};
Round 1C
250pts
题意简述
给出
特殊地,只含一个元素的数组也是加法封闭的。
判断这个数组是不是加法封闭的。
数据范围
思路
一堆特判,没什么可说的。
数据范围这么小,随便做。
时间复杂度
代码
#include<vector>#include<string>using namespace std;class SumFullSet{ public: string isSumFullSet(vector<int> s) { int n=s.size(); string yes="closed"; string no="not closed"; if (n==1) return yes; int pos=0,neg=0,zer=0; int a,b; for (int i=0;i<n;i++) if (s[i]==0) zer++; else if (s[i]>0) pos++,a=s[i]; else neg++,b=s[i]; if (pos>1||neg>1) return no; if (zer) if (pos==1&&neg==1&&a==b) return no; else return yes; else return no; }}
500pts
题意简述
给出一个只包含ABC的字符串
判断是否可以将
数据范围
思路
贪心。
求出ABC当前剩余字符每种至少需要多长能放下。
每次找合法的长度最大的接到后面。
如果找不到就返回impossible
时间复杂度
代码
#include<cstdio>#include<string>using namespace std;class ThreeProgrammers{ public: string validCodeHistory(string st) { string ret; int mx,pos,len; int num[3]={0},val[3],last[3]={-3,-3,-3}; len=st.length(); for (int i=0;i<len;i++) num[st[i]-'A']++; for (int i=0;i<3;i++) val[i]=(num[i]-1)*(i+1)+1; for (int i=0;i<len;i++) { mx=0,pos=-1; for (int j=0;j<3;j++) if (val[j]>mx&&i-last[j]>=j+1) mx=val[j],pos=j; if (pos==-1) return string("impossible"); last[pos]=i; val[pos]-=pos+1; ret+=pos+'A'; } return ret; }}
1000pts
题意简述
给出三个数
设字符串
设
求
数据范围
思路
无
代码
无
Round 2A
400pts
题意简述
给出含有
问这个数有没有可能是
数据范围
思路
这题太恶心了…解释起来也好麻烦= =
进行一下模型转换,2的系数
Possible的情况:
- 如果原数组本来就有
x ,检查其他数中a 的最小值是否≤xa ,b 的最小值是否≤xb 。因为我们可以先对其他所有数都取gcd,最后对这个结果与x 再取一次gcd,从而得到x 。
同理,检查其他数a 和b 的最大值。 - 如果两个数各有一个系数和
x 的系数相等,并且它们同为最小或者同为最大。
在图中表示为两条线有交叉,并且取值在同侧。 - 如果两个数分别有一个系数满足
x ,但是它们不满足同为最小或者同为最大,但是有第三个数横跨它们… 上图好了…但是只能这个方向交,不能另一个方向…因为我们可以维护两条交叉线段的同侧不变,所以这样是对的…
其他的情况都是Impossible
感觉说的好乱…
时间复杂度O(n3)
代码
#include<cstdlib>#include<string>#include<vector> #include<iostream>using namespace std;#define INF 0x3f3f3f3fclass LCMGCD{ public: struct data{ int a,b; }d[100],need; int n,tmp,mina,minb,maxa,maxb; bool ok; string isPossible(vector<int> s,int p) { n=s.size(); if (n==1) if (s[0]==p) return string("Possible"); else return string("Impossible"); for (int i=0;i<n;i++) { tmp=s[i]; d[i].a=0; while (tmp%2==0) tmp/=2,d[i].a++; while (tmp%3==0) tmp/=3,d[i].b++; } tmp=p; while (tmp%2==0) tmp/=2,need.a++; while (tmp%3==0) tmp/=3,need.b++; mina=minb=INF; for (int i=0;i<n;i++) { if (d[i].a==need.a&&d[i].b==need.b) { for (int k=0;k<n;k++) if (k!=i) { mina=min(mina,d[k].a); minb=min(minb,d[k].b); maxa=max(maxa,d[k].a); maxb=max(maxb,d[k].b); } if (mina<=need.a&&minb<=need.b||maxa>=need.a&&maxb>=need.b) return string("Possible"); } for (int j=0;j<n;j++) { if (i!=j&&d[i].a==need.a&&d[j].b==need.b) { if (d[i].a>d[j].a&&d[i].b<d[j].b||d[i].a<d[j].a&&d[i].b>d[j].b) return string("Possible"); if (d[i].b>d[j].b) for (int k=0;k<n;k++) if (k!=i&&k!=j&&d[k].a>need.a&&d[k].b<need.b) return ("Possible"); if (d[i].b<d[j].b) for (int k=0;k<n;k++) if (k!=i&&k!=j&&d[k].a<need.a&&d[k].b>need.b) return ("Possible"); } if (i!=j&&d[i].b==need.b&&d[j].a==need.a) { if (d[i].a>d[j].a&&d[i].b<d[j].b||d[i].a<d[j].a&&d[i].b>d[j].b) return string("Possible"); if (d[i].a<d[j].a) for (int k=0;k<n;k++) if (k!=i&&k!=j&&d[k].a>need.a&&d[k].b<need.b) return ("Possible"); if (d[i].a>d[j].a) for (int k=0;k<n;k++) if (k!=i&&k!=j&&d[k].a<need.a&&d[k].b>need.b) return ("Possible"); } } } return ("Impossible"); }};
Regional Wildcard
250pts
题意简述
给出
要求A,B两人每人至少分得一个物品,且两人分得物品的价值和相等,求任意一个方案,或无解。
数据范围
思路
生日悖论。
观察到和的值域为
为了进一步保证正确性,我们构造尽量多的解。可以取前25个数,算出它的所有子集的和,二进制位记录状态。
无解的情况只可能存在于
时间复杂度
代码
#include<cstdio>#include<vector>using namespace std;int ff[25000010];int final[1010];bool flag;int sz;class DivideJewelry{ public: void dfs(int now,int sum,int tmp,vector<int> &v) { if (flag) return; if (ff[sum]&&ff[sum]!=tmp) { flag=true; for (int i=0;i<25;i++) if (!(bool(tmp&(1<<i))^bool(ff[sum]&(1<<i)))) final[i]=0; else if (bool(tmp&(1<<i))) final[i]=1; else final[i]=-1; return; } ff[sum]=tmp; if (now==sz) return; dfs(now+1,sum,tmp,v); dfs(now+1,sum+v[now],tmp|(1<<now),v); } vector<int> divide(vector<int> x) { sz=min(int(x.size()),25); dfs(0,0,0,x); if (!flag) { vector<int> ret; return ret; } else { vector<int> ret(final,final+int(x.size())); return ret; } }};
500pts
题意简述
请你构造一个点数不超过
数据范围
思路
ing..
代码
无
- TCO2016乱做
- TCO2016 R1B
- 乱
- 乱
- 乱
- 乱
- 乱
- 乱
- 乱
- 乱
- 乱
- 乱
- 乱
- 乱
- 乱
- 乱~~~
- 乱
- 乱
- linux 4
- 【Spring从入门到精通】(四)容器的基础XmlBeanFactory
- 使用模板类导致error LNK2019: 无法解析的外部符号
- LeetCode(213) House Robber II
- socket通信
- TCO2016乱做
- Android EditText常用属性功能汇总
- java多态
- SendMessage()
- React—Native开发之 Could not connect to development server(Android)解决方法
- Leetcode22: Generate Parentheses
- UVa1591
- 【Spring从入门到精通】 (五)加载Bean
- linux系统安装