中午upc,只出了一道。
下午刷了两道1400,晚上Atcoder一场。
给出长度为 n 的数列,求每一个位置往后延伸的最短距离,使得这个区间中的所有数为10的倍数。
和之前做过的求总和为x的倍数的最大区间,或者区间个数这样的题 思路相同。
处理前缀和,前缀和取模,判断当前的值是否在前面出现过。如果是,那么中间这一段总和就为x的倍数了。
这里就是要把前面一次该数出现的位置+1这个位置 的答案赋值为这一区间长度就行了。
注意标记0位置为数0出现的位置。
const int N = 200010, mod = 1e9+7;
int T, n, m, a[N];
int f[N];
int main(){
Ios;
cin>>n;
mp[0]=0;
for(int i=1;i<=n;i++){
cin>>a[i];
a[i]=(a[i]+a[i-1])%10;
f[i]=-1;
if(!mp.count(a[i])) mp[a[i]]=i;
else{
f[mp[a[i]]+1]=i-mp[a[i]];
mp[a[i]]=i;
}
}
for(int i=1;i<=n;i++) cout<<f[i]<<" ";
return 0;
}
一个十进制数可以由若干个 每位只包含0或1的十进制数 相加组成。
给出一个数n,能组成的n的数最少为多少个?依次输出。
用进制的角度来看。遍历n的每一位;
如果这一位的数 x 不为0,那么组成n的一个数这一位就为 1,将 x - -,答案串+‘1’;
如果 x 为 0,那么组成 n 的所有数这一位都为 0,答案串+‘0’。
将答案串转化为数字便是一个答案数。
同理,二进制似乎也可以这样做。因为是让组成数最少,那么就需要每一位尽可能的大。所以如果这一位不为0,就把答案数的这一位设为1。
而另一种贪心做法:每次都选不超过n的最大的01数,那么减到最后剩下的就可能不是比较大的01数了,只能由1拼成,这样个数就变多了。
关键是思维的转化。
const int N = 2000010, mod = 1e9+7;
int T, n, m, a[N];
string s;
int ans[N];
int main(){
cin>>n;
s=to_string(n);
int cnt=0;
while(1)
{
string t;
int flag=0;
for(int i=0;i<s.size();i++)
{
int x=s[i]-'0';
if(x) t+='1',x--,flag=1;
else t+='0';
s[i]=x+'0';
}
if(!flag) break;
cnt++;
ans[cnt]=stoi(t);
}
cout<<cnt<<endl;
for(int i=1;i<=cnt;i++) cout<<ans[i]<<" ";
return 0;
}
要把n个数选出若干组。
要求每一组中的 人数
*这组中的最小的a[i]
≥ x。
问,最多分多少组?
为了使得每组的人数更少,要使得每组中最小的a[i]更大。
从大到小将a[i]排序。
遍历每个位置,看当前数能不能作为一组中最小的一个数。
即,看前面是否有x/a[i]上取整个数没有在集合中。
const int N = 200010, mod = 1e9+7;
int T, n, m, a[N];
int main(){
Ios;
cin>>T;
while(T--)
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1,greater<int>());
int ans=0,cnt=0;
for(int i=1;i<=n;i++)
{
int x=a[i];
int t=(m+a[i]-1)/a[i];
cnt++;
if(cnt>=t) cnt=0,ans++;
}
cout<<ans<<endl;
}
return 0;
}
还有一道还没出,明天再看吧。
输出字典序最小的拓扑序列。
把队列换成优先队列,每次都先把入度为0的,最小的点输出。
当时没想出来。。只想着加边,加边。。
这是第二次遇到字典序用优先队列的了!
还有就是:拓扑序列输出顺序就是出队顺序,出队来更新其他点的顺序。
const int N = 200010, mod = 1e9+7;
int T, n, m, a[N];
int e[N*2],ne[N*2],h[N],idx;
int ru[N],que[N*2];
int ans[N],cnt=0;
void add(int x,int y){
e[idx]=y,ne[idx]=h[x],h[x]=idx++;
}
void tpsort()
{
priority_queue<int,vector<int>,greater<int> > que;
for(int i=1;i<=n;i++){
if(!ru[i]) que.push(i);
}
while(que.size())
{
int x=que.top();que.pop();
ans[++cnt]=x;
for(int i=h[x];i!=-1;i=ne[i])
{
int tx=e[i];
ru[tx]--;
if(!ru[tx]) que.push(tx);
}
}
int flag=0;
for(int i=1;i<=n;i++) if(ru[i]>0) flag=1;
if(flag) cout<<-1;
else{
for(int i=1;i<=cnt;i++) cout<<ans[i]<<' ';
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) h[i]=-1;
while(m--)
{
int x,y;cin>>x>>y;
add(x,y);
ru[y]++;
}
tpsort();
return 0;
}
最近有点飘了!