膜你赛2018-02-08
T1
题目传送门
弱智习题
就是分数化小数,让你圈出循环节
我只会把循环小数化成分数
这道题很简单,大力模拟就行了,余数出现循环就说明产生了循环节
具体实现较丑
#include<iostream>
#include<vector>
#include<map>
#include<cstdio>
#include<cstring>
#define MAXN 100010
using namespace std;
int n,d,times,mark;
bool flag;
vector<char>v,temp;
map<int,int>st;
int main()
{
cin>>n>>d;
v.clear(),temp.clear();
st.clear();
int k=n/d;
while(k)
{
temp.push_back(k%10+'0');
k/=10;
}
for(int i=temp.size()-1;i>=0;i--)v.push_back(temp[i]);
if(n<d)v.push_back('0');
v.push_back('.');
st[n%d]=MAXN;
n%=d;
while(1)
{
if(n%d==0)
{
v.push_back('0');
flag=1;
break;
}
n*=10;
v.push_back(n/d+'0');
if(st[n%d])
{
v.push_back(')');
mark=st[n%d];
if(mark==MAXN)mark=1;
else mark++;
break;
}
if(n%d==0)
{
flag=1;
break;
}
st[n%d]=++times;
n%=d;
}
int from=0;
times=0;
if(flag)
{
for(int i=0;i<v.size();i++)
{
putchar(v[i]);
if((i+1)%76==0)putchar(10);
}
return 0;
}
for(int i=0;i<v.size();i++)
{
times++;
if(from&&i-from==mark)putchar('('),times++;
if(v[i]=='.')from=i;
putchar(v[i]);
if(times%76==0)putchar(10);
}
}
真的丑
T2
题目传送门
第一眼以为很难(怕不是我傻)
就是要求最不开心的一天最开心,要求输出字典序最大的方案
很眼熟的问题(最x最y化)
二分即可
坑点:如果有的巧克力没有吃,就都要留到最后一天吃
策略:尽可能少吃,能不吃就不吃,既能保证最优解,又能保证字典序(先吃会随着时间推移造成损失,方案就不优了)
我居然以为这道题难
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 100010
#define ll long long
using namespace std;
inline void read(ll &x)
{
ll s=0,w=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')w=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
s=(s<<3)+(s<<1)+c-'0';
c=getchar();
}
x=s*w;
}
inline void write(ll x)
{
if(x<0)
{
putchar('-'),x=-x;
}
if(x>=10)write(x/10);
putchar(x%10+'0');
}
ll l,r,ans;
ll n,d,w[MAXN],eat_time[MAXN];
inline bool check(ll x)
{
ll eat_index=1,now_happy=0;
for(int i=1;i<=d;i++)
{
now_happy>>=1;
while(eat_index<=n&&now_happy<x)
{
eat_time[eat_index]=i;
now_happy+=w[eat_index++];
}
if(now_happy<x)return false;
}
while(eat_index<=n)eat_time[eat_index++]=d;
return true;
}
int main()
{
read(n),read(d);
for(int i=1;i<=n;i++)read(w[i]),r+=w[i];
while(l<r)
{
ll mid=(l+r)>>1;
if(check(mid))l=mid+1,ans=mid;
else r=mid;
}
printf("%lld\n",ans);
check(ans);
for(int i=1;i<=n;i++)write(eat_time[i]),putchar(10);
}
T3
题目传送门
一道在bzoj 6块钱测评机上能200ms跑过的题,在我校oj完美TLE
老师会改时限吧
堆的习题,其实sort也行?(不确定),贪心的去取最便宜的
本人使用了assass_cannotin的神奇堆模板
–>点击这里,走上人生巅峰–>assass_cannotin的神奇堆模板
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 50010
#define ll long long
using namespace std;
inline void read(ll &x)
{
ll s=0,w=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')w=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
s=(s<<3)+(s<<1)+c-'0';
c=getchar();
}
x=s*w;
}
inline void write(ll x)
{
if(x<0)
{
putchar('-'),x=-x;
}
if(x>=10)write(x/10);
putchar(x%10+'0');
}
template <class T,int max_size,bool compare(const T &a,const T &b)>class Heap
{
private:
T heap[max_size];
int heap_size;
inline void swap(T &a,T &b)
{
T temp=a;
a=b,b=temp;
}
void up(int x)
{
if(x==1)return ;
int y=x>>1;
if(compare(heap[x],heap[y]))
{
swap(heap[x],heap[y]);
up(y);
}
}
void down(int x)
{
int y=x<<1;
if(y>heap_size)return ;
if(y<heap_size&&compare(heap[y+1],heap[y]))y+=1;
if(compare(heap[y],heap[x]))
{
swap(heap[x],heap[y]);
down(y);
}
}
public:
Heap()
{
heap_size=0;
}
inline void insert(T a)
{
heap[++heap_size]=a;
up(heap_size);
}
inline void pop()
{
heap[1]=heap[heap_size--];
down(1);
}
inline T top()
{
return heap[1];
}
inline T pop_out()
{
T temp=heap[1];
heap[1]=heap[heap_size--];
down(1);
return temp;
}
inline void clear()
{
heap_size=0;
}
inline bool empty()
{
return !heap_size;
}
inline int size()
{
return heap_size;
}
};
struct node
{
ll val,id;
}cow[MAXN<<1];
inline bool cmp(const node &a,const node &b){return a.val<b.val;}
Heap<node,MAXN,cmp>Q1,Q2;
bool buy[MAXN];
ll n,k,m,x,y,ans;
int tot;
int main()
{
read(n),read(k),read(m);
for(int i=1;i<=n;i++)
{
read(x),read(y);
cow[++tot].val=x,cow[tot].id=i;
Q1.insert(cow[tot]);
cow[++tot].val=y,cow[tot].id=i;
Q2.insert(cow[tot]);
}
while(true)
{
while(buy[Q1.top().id]&&(!Q1.empty()))Q1.pop();
while(buy[Q2.top().id]&&(!Q2.empty()))Q2.pop();
if(k&&(!Q2.empty())&&(Q2.top().val<Q1.top().val&&Q2.top().val<=m))
{
ans++;
k--;
buy[Q2.top().id]=true,m-=Q2.top().val;
Q2.pop();
}
else if((!Q1.empty())&&Q1.top().val<=m)
{
ans++;
buy[Q1.top().id]=true,m-=Q1.top().val;
Q1.pop();
}
else break;
}
write(ans),putchar(10);
}
T4
学校oj上写的是dp,给我吓坏了
后来发现是个暴搜
虚惊一场
题目传送门
本来尝试了bfs,结果TLE(不是你说是暴搜的吗)
改成记忆化dfs
瞬间跑过
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 510
using namespace std;
inline void read(int &x)
{
int s=0,w=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')w=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
s=(s<<3)+(s<<1)+c-'0';
c=getchar();
}
x=s*w;
}
int map[MAXN][MAXN],front=1,rear=0,dp[MAXN][MAXN];
const int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
int R,C,ans;
int dfs(int x,int y)
{
if(dp[x][y])return dp[x][y];
dp[x][y]=1;
for(int k=0;k<4;k++)
{
int nowx=x+dx[k],nowy=y+dy[k];
if(map[nowx][nowy]<map[x][y])dp[x][y]=max(dp[x][y],dfs(nowx,nowy)+1);
}
return dp[x][y];
}
int main()
{
read(R),read(C);
memset(map,0x3f,sizeof(map));
for(int i=1;i<=R;i++)
{
for(int j=1;j<=C;j++)
{
read(map[i][j]);
}
}
for(int i=1;i<=R;i++)
{
for(int j=1;j<=C;j++)
{
if(!dp[i][j])dfs(i,j);
}
}
for(int i=1;i<=R;i++)
{
for(int j=1;j<=C;j++)
{
ans=(ans<dp[i][j])?dp[i][j]:ans;
}
}
cout<<ans<<endl;
}
真是虎,叫什么dp