1. 战争(war)
题目描述
Yjt 拥有庞大的后宫,但是最近他很烦恼。
他的 n 个后宫住在连续的一排 n 个房间里,每个房间只住一个人,编号为 1..n。他的后
宫来自 m 个不同的国家,每个国家的语言不同,一旦相邻的两个房间住着来自相同国家的
人,她们就会发生争吵,然后爆发可怕的战争,使 yjt 后宫失火。因为后宫实在太多,yjt 也
不知道她们分别来自什么国家,每个后宫都可能是 m 个国家中的任意一个。Yjt 想知道,有
多少种可能的状态会发生战争。
输入格式
第一行两个正整数 m,n. 输出格式
一行一个自然数,表示可能的状态数。答案对 998244353 取模。
样例输入
2 3
样例输出
6
样例解释
可能的状态分别是:
第一个来自 1 国家,第二个来自 1 国家,第三个来自 1 国家
第一个来自 1 国家,第二个来自 1 国家,第三个来自 2 国家
第一个来自 1 国家,第二个来自 2 国家,第三个来自 2 国家
第一个来自 2 国家,第二个来自 2 国家,第三个来自 2 国家
第一个来自 2 国家,第二个来自 2 国家,第三个来自 1 国家
第一个来自 2 国家,第二个来自 1 国家,第三个来自 1 国家
数据范围
对于 30%的数据,n,m<=5;
对于 50%的数据,n,m<=1000000;
对于 100%的数据,n,m<=2147483647
#include<bits/stdc++.h>
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#define mod 998244353
using namespace std;
int n,m,ans=0;
int ksm(int a,int b){
int ans=1;
for(;b;a=(a*a)%mod,b>>=1)
if(b&1) ans*=a,ans%=mod;
return ans;
}
int main(){
freopen("war.in","r",stdin);
freopen("war.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>m>>n;
long long ex=(ksm(m,n)%mod-m*ksm(m-1,n-1)%mod)%mod;
ex+=(ex<0?mod:0);
cout<<ex;
return 0;
}
2.字母(letter)
题目描述
现在有 n 个字母,每个字母都有价值 v[i]和个数限制 num[i]。现在要构造一个任意长度
的串。定义串的价值为:第 1 位字母的价值*1+第 2 位字母的价值*2+第 3 位字母的价值*3。
求能构造出的最大的串的价值。注意由于这个串可以是空的,所以价值一定不会小于 0. 输入格式
第一行一个整数 n,表示字母的数目。
接下来 n 行每行两个数 v[i],num[i],意义如题目所示。
输出格式
一行一个整数表示最大的串的价值。
样例输入
3
-5 3
2 1
1 1
样例输出
5
数据范围
对于 30%的数据,n<=10;
对于另外 20%的数据,v[i]>=0;
对于 100%的数据,n<=100000,|v[i]|<=100,num[i]<=10。
#include<bits/stdc++.h>
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
using namespace std;
int n,l=0,b[1000009];
long long ans=0,ex=0;
struct node{
int v,num;
}a[100009];
bool cmp(int x,int y){
return x>y;
}
int main(){
freopen("letter.in","r",stdin);
freopen("letter.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].v>>a[i].num;
while(a[i].num--) b[++l]=a[i].v;
}
sort(b+1,b+l+1,cmp);
for(int i=1;i<=l;i++){
b[i]+=b[i-1];
}
for(int i=1;i<=l;i++){
ans=max(ans,ans+b[i]);
}
cout<<ans;
return 0;
}
离散化+前缀和
#include<bits/stdc++.h>
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#define N 100086
#define ll long long
using namespace std;
/*int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0',ch=getchar();}
return x*f;
}*/
struct data{int val,cnt;}a[N];
bool cmp(data a,data b){return a.val>b.val;}//从大到小排
int main(){
freopen("letter.in","r",stdin);
freopen("letter.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;cin>>n;//=read();
for(int i=1;i<=n;i++){
cin>>a[i].val>>a[i].cnt;//=read();
}
sort(a+1,a+n+1,cmp);
ll now=0,cnt=0,ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=a[i].cnt;j++){
cnt+=a[i].val;//前缀和,实现a[i].val*i
now+=cnt;
ans=max(ans,now);
}
printf("%lld\n",ans);
return 0;
}
只有前缀和
3.约数研究(number)
题目描述 定义 f(x)为 x 的约数个数。例如 f(2)=2,f(6)=4。给定 n,求出 f(1)到 f(n)的和。 输入格式 一行一个正整数 n。 输出格式 一行一个数表示答案。 样例输入 3 样例输出 5 数据范围 对于 30%的数据,n<=1000; 对于 50%的数据,n<=200,000. 对于 70%的数据,n<=5,000,000; 对于 100%的数据,n<=10^10;
#include<bits/stdc++.h>
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
using namespace std;
int main(){
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
unsigned long long ans=0;
cin>>n;
for(int i=1;i<=n;i++)
ans+=n/i;
cout<<ans<<endl;
return 0;
}
信手拈来的骗分,直上70
#include<bits/stdc++.h>
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#define ll long long
using namespace std;
int n;
ll ans=0;
int main(){
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
scanf("%d",&n);
for(int l=1,r;l<=n;l=r+1){
ll i=n/l;
r=n/i;
ll len=r-l+1;
ans+=len*i;
}
cout<<ans<<endl;
return 0;
}
亿点点,边界优化,拿下100
4.灯(light)
题目描述 月月立志要做一个合格的女仆。 这天晚上月月要关掉楼里所有的灯。这个楼有 n 层,每层有 m 个房间,每层的两侧有 楼梯,只能从楼梯上下楼。每个房间里的灯开关状态由一个大小为 n*(m+2){包括两边的楼 梯}的 01 矩阵表示,0 代表关着的,1 代表开着的。每次向左或者向右移动一格会消耗一分 钟,从楼梯上下楼也会消耗一分钟,但是走到房间里关灯不需要消耗时间。一开始月月在矩 阵左下角,现在她想知道她最少需要多少分钟才能把所有的灯全部关上。 输入格式 第一行包含两个正整数 n,m,表示楼有 n 层,每层 m 个房间。 接下来 n 行每行 m+2 个整数,表示这一层 m 个房间的状态。注意楼梯的部分始终是 0。 输出格式 一行一个整数表示答案。 样例输入 3 4 001000 000010 000010 样例输出 12 数据范围 对于 30%的数据,n*m<=12 对于 100%的数据,n<=8,m<=100
#include<bits/stdc++.h>
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
using namespace std;
typedef long long ll;
ll l[155],r[155],mx,n,m,ans;
char a[155][155];
void dfs(ll i,ll lr,ll now)//当前第i行,lr是在左边1还是右边2 now当前的时间
{
if(i==mx){
if(l[i]==0) {ans=min(now,ans);return;}
if(lr==1){//lr是在左边
now+=r[i]-1;
}
else{
now+=m+2-l[i];
}
ans=min(now,ans);return ;
}
if(lr==1){//在左边
if(l[i]==0){//这行没有要关的灯
dfs(i+1,1,now+1);}// 下一行
else{dfs(i+1,1,now+2*(r[i]-1)+1);}//这边有要关的灯,关完再原路回
dfs(i+1,2,now+m+2); //粗爆走一行 走到最右边
}
else{//在右边
if(l[i]==0) dfs(i+1,2,now+1); else dfs(i+1,2,now+2*(m+2-l[i])+1);
dfs(i+1,1,now+m+2);
}
}
int main()
{
freopen("light.in","r",stdin);
freopen("light.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m;getchar();
mx=1;
for(ll i=n;i>=1;i--){
for(ll j=1;j<=m+2;j++)
{
a[i][j]=getchar();
if(a[i][j]=='1')//如果当前行有灯要关
{
if(l[i]==0){ //i行第一次遇到有灯要关
l[i]=j;//记录亮灯所在的列
}
r[i]=j;//记录当前行右边界1
if(mx==1) mx=i;//mx记录有灯的最大行号
}
}getchar();
}
ans=6147483647;
dfs(1,1,0);
cout<<ans<<endl;
return 0;
}
dfs遍历,getchar()读字符,(居然是读字符串,奇坑)