Dashboard - Codeforces Round #566 (Div. 2) - Codeforces
题意:给你一个的表格,你要用小L型的瓷砖把整个表格填满,问你有多少种方法?
知识点:数学,思维
思路:通过一点点观察发现,想要满足宽度是3,一定是俩个L型瓷砖交叉这放,并且对于一个长度为2宽度为3的表格,只有两种放法,如下图
所以只有表格长度为偶数,那么答案一定是2^n/2(有多少个长度为2的,每个有两种情况)
奇数一定不可能填满,因为没有长度为1的图形来填,也不可能凑出来。
代码
#include
using namespace std;
typedef long long ll;
const ll N = 1e5+5;
const ll mod =1e9+6;
void solve(){ll n;cin>>n;if(n&1)cout<<0<<&#39;\n&#39;;//奇数没有else cout<<(1ll<<(n/2))<<&#39;\n&#39;;//偶数 2^(n/2)个
}
int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int _&#61;1;//cin>>_;while(_--){solve();}return 0;
}
/*
*/
题意&#xff1a;有一个大小的表格&#xff0c;表格上每一个位置只会出现两种字符&#xff0c;‘&#43;’和‘.’&#xff0c;问是否所有的‘&#43;’连接成了一个大的 &#43; 号&#xff08;所有‘&#43;’字符都在这个大的 &#43; 号上&#xff0c;大的 &#43; 号四个延伸出去的边长度至少大于等于1&#xff0c;宽度等于1&#xff0c;中间不能是空的&#xff09;&#xff1f;
知识点&#xff1a;搜索&#xff0c;思维
思路&#xff1a;我们先看每一个点是否可以是大 &#43; 号中间那个点&#xff0c;如果是放入我们的数组里&#xff0c;然后先判断数组的大小&#xff0c;如果大小大于1或者等于0&#xff0c;就是说不满足所有的点都在大的 &#43; 号上或者说 大的 &#43; 号的边的宽度大于1&#xff0c;这些都是NO的&#xff0c;现在只剩下了数组大小等于1&#xff0c;我们搜4个方向上所能走的点打上标记&#xff0c;最后看整个图&#xff0c;如果存在没有打上标记的‘&#43;’&#xff0c;说明不是所有的‘&#43;’构成了大的 &#43; 号&#xff0c;输出NO&#xff0c;否则输出 YES
代码
#include
using namespace std;
typedef long long ll;
const ll N &#61; 1e5&#43;5;
const ll mod &#61;1e9&#43;6;
char mp[505][505];
ll n,m;
bool vis[505][505];
vector
ll dx[5]&#61;{0,0,0,1,-1};
ll dy[5]&#61;{0,1,-1,0,0};
bool check(ll x,ll y){for(int i&#61;0;i<5;&#43;&#43;i)if(mp[x&#43;dx[i]][y&#43;dy[i]]!&#61;&#39;*&#39;)return false;return true;
}
void solve(){cin>>n>>m;for(int i&#61;1;i<&#61;n;&#43;&#43;i){for(int j&#61;1;j<&#61;m;&#43;&#43;j){cin>>mp[i][j];if(mp[i][j]&#61;&#61;&#39;.&#39;)vis[i][j]&#61;true;//先给&#39;.&#39;打上标记这样好判断一点}}for(int i&#61;2;i
}
int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int _&#61;1;//cin>>_;while(_--){solve();}return 0;
}
/*
*/
题意&#xff1a;给你n个字符串&#xff0c;现在问你能从中选出的美好的诗句有几条&#xff1f;
美好的诗句满足&#xff1a;
&#xff08;1&#xff09;美好的诗句由4个字符串组成&#xff0c;分为左上&#xff0c;左下&#xff0c;右上&#xff0c;右下。
&#xff08;2&#xff09;左上和左下的元音字母个数要相同。
&#xff08;3&#xff09;右上和右下的元音字母个数要相同&#xff0c;并且右上和右下的最后一个元音字母一样。
&#xff08;元音字母只包括 a,e,i,o,u&#xff09;
知识点&#xff1a;贪心&#xff0c;排序
思路&#xff1a;发现条件&#xff08;3&#xff09;是包含条件&#xff08;2&#xff09;的&#xff0c;所以肯定是条件&#xff08;3&#xff09;满足的越多越好&#xff0c;因为多余的可以退化成满足&#xff08;2&#xff09;&#xff0c;所以现在问题转化成了问有多少个满足条件&#xff08;3&#xff09;的字符串对和剩下的有多少个满足条件&#xff08;2&#xff09;的字符串对。这个我们可以先按元音字母个数从小到大排序&#xff0c;再按最后一个元音字母的大小从小到大排序&#xff0c;然后按要求找就OK了&#xff0c;具体实现可以看代码。
代码
#include
using namespace std;
typedef long long ll;
const ll N &#61; 1e5&#43;5;
const ll mod &#61;1e9&#43;6;
struct dd{ll cnt,last;//元音字母个数&#xff0c;最后一个元音字母string s;//这个字符串是什么inline bool operator <(const dd &r)const{if(cnt&#61;&#61;r.cnt)return last
bool vis[N];//打标记用
void solve(){ll n;cin>>n;for(int i&#61;1;i<&#61;n;&#43;&#43;i){string s;cin>>s;ll cnt&#61;0,last&#61;0;for(int i&#61;0;i
int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int _&#61;1;//cin>>_;while(_--){solve();}return 0;
}
/*
*/
题意&#xff1a;给你一颗有n个结点的无根树&#xff0c;问你是否能找到一个点作为根满足&#xff1a;
对于任意两点满足并且
(表示点i到点j之间的边的数量&#xff0c;表示点i和多少个点直接相连)
找到输出点的编号&#xff0c;找不到输出-1
知识点&#xff1a;DFS&#xff0c;树的重心
思路&#xff1a;如果暴力的想&#xff0c;就是n个点都可能成为根&#xff0c;每个都判一次&#xff0c;复杂度O()肯定是不可以的&#xff0c;所以想尽可能减少判的次数&#xff0c;发现有一些点是没有判的必要的&#xff0c;所以现在就是考虑哪些点可能成为根
先考虑条件&#xff0c;这两个条件要都满足一定是这个点孩子的子树都是同构的&#xff0c;而想要满足这个条件&#xff0c;那么这个点可能在树的重心位置上&#xff0c;所以重心是可能成为根的一个点&#xff0c;然后考虑重心的孩子&#xff0c;如果孩子的子树是一个树型的&#xff0c;那这个子树上的所有点都不可能是根&#xff0c;因为上面所有点都不可能满足条件的。如果孩子的子树一个链型的&#xff0c;那这个子树的叶子是可能成为根的&#xff0c;但其实这里不用全判&#xff0c;如果俩个链长度相同&#xff0c;取其一就行&#xff0c;毕竟是同构的&#xff0c;所以我们要判断的就很少了。
&#xff08;这道题其实多动手画图就能发现了&#xff09;
代码
#include
using namespace std;
typedef long long ll;
const ll N &#61; 1e5&#43;5;
const ll mod &#61;1e9&#43;7;
ll n;
ll siz[N],weight[N];//求重心用的
ll treefocus[2];//树的重心下标
vector
void dfs(ll u,ll root){//求树的重心siz[u]&#61;1;weight[u]&#61;0;for(auto v:mp[u]){if(v&#61;&#61;root)continue;dfs(v,u);siz[u]&#43;&#61;siz[v];weight[u]&#61;max(weight[u],siz[v]);}weight[u]&#61;max(weight[u],n-siz[u]);if(weight[u]<&#61;n/2){//根据定义判断树的重心treefocus[treefocus[0]!&#61;0]&#61;u;}
}
vector
ll d[N],ye,Maxdeep;//度数&#xff0c;叶子的下标&#xff0c;链的长度
bool tp,in[N];//是不是链&#xff0c;有没有放过
void DFS(ll u,ll root,ll deep){ll ge&#61;1;//孩子个数Maxdeep&#61;max(Maxdeep,deep);for(auto v:mp[u]){if(v&#61;&#61;root)continue;DFS(v,u,deep&#43;1);ge--;}if(ge&#61;&#61;1)ye&#61;u;//叶子没有孩子if(ge<0)tp&#61;false;//个数小于0了&#xff0c;说明不是链
}
bool flag;
ll op[N],maxdeep;
void check(ll now,ll root,ll deep){//判断是不是满足条件maxdeep&#61;max(maxdeep,deep);if(op[deep]){//同一深度&#xff0c;度数要相等if(d[now]!&#61;op[deep])flag&#61;false;}else op[deep]&#61;d[now];for(auto v:mp[now]){if(v&#61;&#61;root)continue;check(v,now,deep&#43;1);}
}
void solve(){cin>>n;for(ll i&#61;1,u,v;i
int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int _&#61;1;//cin>>_;while(_--){solve();}return 0;
}
/*
*/
题意&#xff1a;,已知的值&#xff0c;求?
知识点&#xff1a;矩阵快速幂&#xff0c;欧拉定理
思路&#xff1a;发现最后一定等于,所以我们可以构造一个关于这几项幂的矩阵&#xff0c;然后矩阵快速幂加速&#xff0c;我是通过分别构造的矩阵和的矩阵来写的。
其中分别表示答案中的多少次幂
其中表示答案中的多少次幂
最后输出就可以了&#xff08;矩阵里是对phi(1e9&#43;7)取模&#xff0c;因为欧拉定理&#xff09;
代码
#include
using namespace std;
typedef long long ll;
const ll N &#61; 1e5&#43;5;
const ll mod &#61;1e9&#43;6;
const ll Mod &#61;1e9&#43;7;
const int maxl&#61;105;
struct Matrix {ll a[maxl][maxl];int n,m;inline Matrix(int n,int m) : n(n) , m(m) {for(int i&#61;0;i
};
ll ksm(ll a,ll b){ll ans&#61;1;while(b){if(b&1)ans&#61;ans*a%Mod;a&#61;a*a%Mod;b>>&#61;1;}return ans;
}
ll f[3],n,c;
void solve(){cin>>n;for(int i&#61;2;i>&#61;0;--i)cin>>f[i];//倒着输入对标一下cin>>c;Matrix now(3,3);for(int i&#61;0;i<3;&#43;&#43;i)now.a[0][i]&#61;1;//构造f1,f2,f3now.a[1][0]&#61;now.a[2][1]&#61;1;// 矩阵 矩阵里是对phi(1e9&#43;7)取模now&#61;now.ksm(n-3);ll ans&#61;1;for(int i&#61;0;i<3;&#43;&#43;i){f[i]&#61;ksm(f[i],now.a[0][i]);ans&#61;ans*f[i]%Mod;//更新答案}Matrix cl(5,5);for(int i&#61;0;i<3;&#43;&#43;i)cl.a[0][i]&#61;1; //构造ccl.a[0][3]&#61;2;cl.a[0][4]&#61;mod-4; //的cl.a[1][0]&#61;cl.a[2][1]&#61;cl.a[3][3]&#61;cl.a[3][4]&#61;cl.a[4][4]&#61;1;//矩阵cl&#61;cl.ksm(n-3);ll w&#61;(cl.a[0][3]*3ll%mod&#43;cl.a[0][4])%mod;//对phi(1e9&#43;7)取模,因为是次幂cout<
int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int _&#61;1;//cin>>_;while(_--){solve();}return 0;
}
/*
*/
题意&#xff1a;给你四个整数&#xff0c;问你函数在中找到最小的x让y最大&#xff1f;
知识点&#xff1a;类欧几里德&#xff0c;扩展欧几里得&#xff08;需要一定的数论基础
思路&#xff1a;根据一点点高中知识&#xff0c;可以知道在时候取到最大值&#xff0c;所以我们要
也就是等价于尽可能趋近0或者2q,
我们可以考虑二分的对q的偏差&#xff0c;
我们首先要知道一个定理&#xff1a;等价于
这个也很好验证:如果,后面那个等于-1-(-1)&#61;0
如果,后面那个等于0-(-1)&#61;1
如果,后面那个等于0-0&#61;0
如果存在x满足,那么一定满足
后面这个其实就是一个类欧几里德的东西&#xff0c;(类欧几里德就不展开讲了&#xff0c;这里就用了个板子)然后我们就能二分出来对q的最小偏差d
也就是我们知道和
现在我们要还原x的值&#xff0c;发现这俩个就是个同余方程&#xff0c;我们用扩展欧几里得解一下就好了
还原出来x记得要把x再更新到这个区间里&#xff0c;取两者的最小值就行了
代码
#include
using namespace std;
typedef long long ll;
const ll N &#61; 1e5&#43;5;
const ll mod &#61;1e9&#43;7;
ll calc(ll a,ll b,ll c,ll n){//类欧几里德if(n<0)return 0;if(n&#61;&#61;0)return b/c;if(a>&#61;c||b>&#61;c)return n*(n&#43;1)/2*(a/c)&#43;(n&#43;1)*(b/c)&#43;calc(a%c,b%c,c,n);ll m&#61;(a*n&#43;b)/c;return m*n-calc(c,c-b-1,a,m-1);
}
ll a,b,p,q,Q,P,x,y,g;
bool check(ll l,ll r){return calc(P,Q-l,Q,b)-calc(P,Q-l,Q,a-1)-calc(P,Q-r-1,Q,b)&#43;calc(P,Q-r-1,Q,a-1);//这里的Q-l和Q-r-1和l,r-1是一样的&#xff0c;只不过防止了负数
}
ll exgcd(ll a,ll b,ll &x,ll &y){//扩展欧几里得if(!b){x&#61;1;y&#61;0;return a;}ll g&#61;exgcd(b,a%b,x,y);ll tmp&#61;x;x&#61;y;y&#61;tmp-(a/b)*y;return g;
}
void solve(){cin>>a>>b>>p>>q;Q&#61;q<<1;P&#61;p<<1;ll l&#61;0,r&#61;q,mid;while(l<&#61;r){//二分偏差mid&#61;l&#43;r>>1;ll L&#61;q-mid,R&#61;q&#43;mid;//偏差后的两个值if(check(L,R))r&#61;mid-1;else l&#61;mid&#43;1;}g&#61;exgcd(P,Q,x,y);ll ans&#61;1e18;//默认最大值if((q-l)%g&#61;&#61;0){ll t&#61;Q/g,now&#61;(x*((q-l)/g)%t&#43;t)%t;while(now>&#61;a)now-&#61;t;//限制成最小while(now&#61;a)now-&#61;t;//限制成最小while(now}
int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int _&#61;1;cin>>_;while(_--){solve();}return 0;
}
/*
*/